JAVA 面试集锦

面试题集锦(重点问题)

主要涉及

  • 集合
  • 线程
  • 线程池
  • Mybatis
  • Spring
  • Mysql & Oracle
  • 设计模式
  • redis
  • springCloud 及其微服务
  • dubbo
  • 消息队列

设计模式

1. 你常用的设计模式有哪些?

  1. 代理模式 Spring Aop 的实现就是使用了动态代理
  2. 工厂模式 连接工厂 CF 会话工厂 SF
  3. 包装模式 IO流 BufferInputStream -》
  4. 策略模式 同一个接口 多种不同的实现类-
  5. 单例模式
// 懒汉式
private A() {}
public static A getA(){
	return new A();
}

// 醉汉式
private A{}
private static final A a;
public static sychronized A getA(){
	return a;
}
  1. 观察者模式 监听器

集合

1. 多线程如何解决并发错误?

首先该问题等同于

  • 线程是如何实现同步的
  • 请说一说你了解的线程

想要回答这个问题呢 , 我希望能够全面的对这个问题进行回答, 那么先由线程聊起

线程是什么?

线程是操作系统能够进行运算调度的最小单位,一个进程可以包含很多的线程。

线程的状态有哪些

  • 1 新生状态 new
    是在new Thread() 即线程进入新生状态

  • 2 就绪状态 Runnable

在线程执行start() 方法之后 ,线程进入就绪状态, 在此状态的线程 会想尽办法的去进入运行状态, 此时是等待 系统调度的获取CPU 的时间片

  • 3 运行状态 Running
    线程获得时间片即可进入运行状态, 在此状态的线程会执行线程run() 中的方法 。
 yield() 会使得当前线程让出时间片 返回就绪状态
 wait() 使得当前线程进入阻塞队列 并且释放锁标记
 sleep() 使当前线程进入阻塞队列, 也就是等待池 ,并不会释放所标记
 join()   t.join 阻塞当前正在执行的线程 知道t线程执行结束, 再执行当前线程
  • 4 阻塞状态 Blocked

阻塞状态分为一下几种

// 等待阻塞
	由 sleep wait join 等进入的阻塞
// 同步阻塞
  由于sychronized 未获得锁标记 或者获得锁标记失败
// 其他阻塞
通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。sleep()不释放锁
  • 5 消亡状态 Dead
    一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

== 创建线程有哪些方式?==

  1. 继承Thread 类
  2. 实现Runable 可以实现多继承
  3. 实现 Callable 有返回值 可抛出异常 包含Future 对象

线程同步是什么?
线程的同步以及解决并发错误 ,都是如何实现多个线程对同一个临界资源进行 操作并保证其不会出现错误。

例举 单例模式中出现的线程安全问题

如何解决线程同步问题

  • sychronized 关键字
    对临界资源上锁(这是一种悲观锁, 对经常需要查询的临界资源上锁, 未获取锁标记的线程则不允许对其进行任何操作)
sychronized 的锁升级->  无锁,偏向锁 轻量级锁  重量级锁
  • java.util.concurrent.ReentLock 可重入锁
    同 sychronized 不同 它需要手动去unlock
有关于其原理层面-- > 有待深入

  • ThreadLocal
    该类管理的变量在每个线程中都有自己的副本,副本之间相互独立,因此获得的结果和其他不同, 但是 可能会导致内存泄漏
ThreadLocalMap 实际上是一个 HashMap

Map<线程, 对象>
  • CountDownLock 插销 ,
  • volatile 实现线程可见性
  • wait与notify 配合 锁可实现 线程交替执行, 同样可实现线程同步
  • BlockingQueue 阻塞队列实现线程同步
  • AtomicInteger.使用原子变量实现线程同步
  • 通过线程池的Callback回调 Callable
  • CyclicBarrier 可实现 循环执行线程

不同的是他允许一组线程相互之间等待,达到一个共同点,再继续执行。可看成是个障碍,所有的线程必须到齐后才能一起通过这个障碍


2 简单介绍一下你所了解的线程池?

在这里插入图片描述

since JDK1.5

线程池呢 主要也是concurrent(并发) 包下实现了 Executor 接口 的ExecutorService 接口 我们主要使用的事 ThreadPoolExecutor
我们可以调用其execute()方法或者submit()方法把工作任务添加到线程中。

我们为什么要使用线程池?

线程分为系统级线程与用户级线程, 普通情况下 用户级的线程与系统级的线程是一一对应的 , 而这样则会使得系统的负载很大, 于是我们可以使用线程池来管理用户级线程使得其 由一一对应变为 多对一。 由此提高线程的利用率 。 从另一个方面来讲, 线程的创建与销毁是需要浪费很多资源的, 所以我们使用线程池来管理线程 则会省下这些临界资源。

线程池的分类(JDK 提供的默认的线程池)

Java通过Executors提供四种线程池,分别为:
//创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
ExecutorService pool =Executors.newCachedThreadPool
//创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
ExecutorService pool =Executors.newFixedThreadPool 
//创建一个定长线程池,支持定时及周期性任务执行。
ExecutorService pool =Executors.newScheduledThreadPool 
//创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
ExecutorService pool =Executors.newSingleThreadExecutor

自定义线程池 (通过构造方法创建线程池)

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

corePoolSize 核心线程数: 线程池创建开始即创建
maximumPoolSize 最大线程数 当阻塞队列与核心线程数满了则会新建线程
keepAliveTime 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间
unit keepAliveTime 参数的时间单位
workQueue 阻塞队列 -> 使用何种的阻塞队列 BlockingQueue接口下的实现类
threadFactory 执行程序创建新线程时使用的工厂
handler 拒绝策略,当线程不够用并且保持任务的队列也满了的时候使用

RejectedExecutionHandler 拒绝策略的分类

  1. AbortPolicy 丢弃任务并抛出RejectedExecutionException异常
  2. DiscardPolicycy:丢弃任务,但是不抛出异常
  3. DiscardOldestPolicy 丢弃队列最前面的任务
  4. CallerRunsPolicy 由调用线程处理该任务

阻塞队列的分类
5. ArrayBlockingQueue 基于数组的阻塞队列,有界队列,按照先进先出(FIFO)的形式
6. LinkedBlockingQueue 基于链表的阻塞队列,元素按照先进先出(FIFO)的策
7. SynchronousBlockingQueue 容量为0,不存储任务,通俗地讲就是有一个处理一个
8. PriorityBlockingQueue 这是一个无界有序的阻塞队列,排序规则和之前介绍的PriorityQueue一致,只是增加了阻塞操作


3 讲一下集合吧

碰到这种问题真的是 -》》》》》

几个方面

  • 底层数据结构
  • 线程安全否?
  • 扩容机制
介绍一下常见的集合, 以及继承关系

在这里插入图片描述


【JCF】

						Collection implement Iterator    								
	List										Set		        
ArrayList Vector LikedList Stack 		 HashSet	SortedSet		
									LinkedHashSet		TreeSet

modcount (由于这个修改计数器  故不可for 循环中修改容器内的元素)

			Map
HashMap				SortedMap		HashTable
					TreeMap



详细的讲一下 List 下集合异同

ArrayList
ArrayList底层是基于数组实现的,是一个动态数组,自动扩容。
ArrayList不是线程安全的,只能用在单线程环境下。
实现了Serializable接口,因此它支持序列化,能够通过序列化传输;
实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问;
实现了Cloneable接口,能被克隆。

  • [数据结构]
    数组
  • [扩容机制]
    初始大小 10
    JDK 1.7 之前 初始容量*3/2 + 1
    JDK 1.7 之后 初始容量 /2 + 初始容量
  • [线程安全]
    不安全

LinkedList

  • [数据结构]
    双向链表
  • [扩容机制]
    不需要扩容-
  • [线程安全]
    不安全

Satck
[数据结构]

  • [扩容机制]

  • [线程安全]
    不安全
    Vector

  • [数据结构]
    数组

  • [扩容机制]
    默认扩容方式为原来的2倍

  • [线程安全]
    安全

详细的讲一下 Set 下集合的异同

HashSet

底层其实是HashMap 故其数据结构与扩容机制与HashMap 是相同的

TreeSet
底层其实是 TreeMap 故其数据结构与扩容机制与TreeMap 是相同的

LinkedHashSet
底层在使用了 Hash 之后 又添加了一个链表

详细的讲一下 Map 下集合的异同

HashMap
since JDK 1.2

比较复杂---------

  • [数据结构]

JDK1.7 数组+ 链表 – 头插法

JDK 1.8 数组+链表+红黑树 — 尾插法

  • [扩容机制]
    JDK1.7
    默认大小为16,负载因子0.75,阈值12

JDK 1.8
Hash 桶默认16 个分组

  • [线程安全]
    不安全
    TreeMap

  • [数据结构]

  • [扩容机制]

  • [线程安全]
    不安全
    HashTable
    since JDK 1.0

  • [数据结构]

  • [扩容机制]
    默认11 个小组 %分组组数

  • [线程安全]
    安全

底层使用了大量的 synchronized 所以县城安全 但是效率低

线程安全下你常用的集合有哪些?

ConcurrentSkipListMap

CopyOnWriteArraylist

ConcurrentHashMap

BlockingQueue

List Set Map 三种集合有什么异同

唯一性与有序性

List 有序 不唯一
Set 无需 唯一(HashCode + equals)实现了sortedset接口的可以有序
Map 无序 键唯一 值不唯一


Override 与 Overload

Override 方法重写 有继承关系

Overload 方法重载 在同一个类下 参数不同

数组转成集合 集合转成数组

List list = Arrays.asList(数组)
Object[] ok = list.toArray()

Object 类的统一父类

toString clone finalize equals hashCode wait notify notifyAll getClass

如何遍历Map 集合

keySet() values() entrySet()
lambda


杂项

String StringBuffer StringBuilder

String 常量池机制 += 时候 每次都去新建一个对象

StringBuffer & StringBuilder
使用 缓存 与 扩容机制 -

无参构造初始容量为:16
有参构造初始容量为:字符串参数的长度+16

一次追加长度超过当前(初始)容量,则会按照 当前(初始)容量2+2 扩容一次
一次追加长度不仅超过初始容量,而且按照 当前容量
2+2 扩容一次也不够,其容量会直接扩容到与所添加的字符串长度相等的长度。之后再追加,还会按照 当前容量*2+2进行扩容

StringBudder 线程不安全
StringBuilder 线程安全

用java 实现简单缓存

Map<String, Object>
ThreadLocal<线程, 对象>

JDK1.8 新特性

lambda

synchronized 优化 —— 不同的锁机制 CAS ABA 自旋锁

synchronized 优化

基本思路是 自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量

CAS 乐观锁 compare and swap (比较并交换)
一般使用 版本号实现其锁 (无锁机制)

自旋锁
自旋锁原理非常简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋)

自旋锁时间阈值(1.6 引入了适应性自旋锁)

自旋锁的开启
JDK1.6 中-XX:+UseSpinning 开启;-XX:PreBlockSpin=10 为自旋次数;JDK1.7 后,去掉此参数,由 jvm 控制;

ABA 问题

Netty NIO 与 BIO

Bio 使用原生的socket 实现 一个链接一个线程

NIO 有缓冲池 Buffer Channel Selector , 将多个链接放进Buffer 由Selector 为其选择Chanel 建立链接,可以由多个Selector

Netty 是一个基于Nio 的 封装了 NIO的一个 异步通信框架
是 Dubbo 框架中通信组件,还有 RocketMQ 中生产者和消费者的通信

synchronized 与 lock 的区别

在这里插入图片描述

公平锁与非公平锁?

1、公平锁能保证:老的线程排队使用锁,新线程仍然排队使用锁。
2、非公平锁保证:老的线程排队使用锁;但是无法保证新线程抢占已经在排队的线程的锁。

解析XML 几种常用的 类及其 理解 dom4j

在这里插入图片描述


Oracle 与 Mysql

sql去重

  • 查询重复的数据 (distinct)
select * from emp where deptno in 
(select deptno from emp group deptno having count(deptno) > 1);
  • 删除重复的数据
delete from lyric 
where content in (select content from lyric group by content having count(content) > 1 and rowid not in (select min(rowid) from lyrix group by content having count(content) > 1)) 

Oracle 的分组函数

max() min() avg() sum() count()

索引有哪些?

普通索引 normal
唯一索引 unique
位图索引 bitmap (分类索引)
函数索引(属于 普通索引)

union 与 union all 区别

union : 对两个结果集进行并集的操作 : 不包括重复行 同时按照默认规则排序
union all 对两个结果集进行并集的操作, 包括重复行, 不进行排序

Oracle 的执行计划

听说过

聊一下sql 优化 (数据量很大怎么办)

  1. 选择最有效的表名顺序
  2. 表之间的链接写在 where 之前
  3. 带统配符的语句时, ‘%’ 在首位 那么字段上建立的主键或者索引将会失效
  4. 使用 truncate 代替 delete
  5. 避免使用having 子句 。
  6. 减少对表的查询
  7. 用in 代替 or
  8. 删除重复的数据
  9. 避免使用耗费资源的操作 ( distinct union minus intersect order by 会进行排序操作)
  10. 自动选择索引
  11. 避免在索引列上使用函数
  12. 用索引提高效率 (但是也不是越多越好 , 多了 增删改 会耗费更大的资源)
  13. 用 >= 代替 > 避免使用 <> 和 NOT
  14. 在字符型字段上加引号。 不加引号索引会失效

读取频繁使用乐观锁, 写入频繁使用悲观锁

事务的隔离级别 (Mysql 与 Oracle 默认的是?)

隔离性问题

  • 脏读 失误A增加了一条记录未提交, 这时候B 读取到了增加后的数据, 然后A 执行了回滚。
  • 不可重复读 一次读取到记录之后其他事务对这条数据进行了修改, 在此读取到的数据不一致
  • 幻读 事务A对表新增并提交, 事务B 再次读取 发现数据多了。

隔离级别

  • 未提交读: 脏读 不可重复读 幻读
  • 提交读 不可重复读 幻读 Oracle
  • 可重复读 幻读 Mysql
  • 序列化

连表查询的方式

  1. 内连接 inner join
  2. 外连接 outer join on
  3. 左外连接 left join on
  4. 右外连接 right join on
  5. 全外连接 full on

事务的四个特征

事务的特征
原子性 事务不可再分
一致性 数据类型保持一致
隔离性 多个事物之间产生的一些隔离性问题
持久性 事务能够将数据持久化到数据库中

mysql 获取当前时间

  1. 将字段设置未 TimeStamp
  2. 将默认值 设置为 Current_TimeStamp

###Mysql _ 与 % 的区别
%代表任意个
_ 代表单个字符

数据库中的索引是什么?

索引是对数据库表值排序的一种结构, 使用索引可以快速访问数据库中特定的信息。

Oracle 与 Mysql 分页 区别

  • mysql:
    select 字段 from 表 limit 起始索引, 显示记录数

  • oralce
    select rownum, a.* from (select rownum rn , 表.* from 表 where rownum <= 20) a where a.rn >= 11;

前端相关

MVVM

Jquery 常用的选择器

js 中Promise 的作用

js 中闭包是什么(闭包可以作用在哪里?)

闭包是可以在另一个函数的外部访问到其作用域中的变量的函数。而被访问的变量可以和函数一同存在。即使另一个函数已经运行结束,导致创建变量的环境销毁,也依然会存在,直到访问变量的那个函数被销毁

vue 如何防止xss攻击

在v-html 中 仅支持 标签与 css 不支持 js


Mybatis

MyBatis 的流程

  1. 通过SqlSessionFactionBuilder 去创建SqlSessionFactory
SqlSessionFactory sf = SqlSessionFactionBuilder.build("mybatis-config.xml") 并将其解析的数据存放到 Configuration 对象中, 然后创建并且会返回一个 DefaultSqlSessionFactroy
  1. 通过 SqlSessionFactory 创建SqlSession 用于执行 sql 语句
  2. 通过sqlSession 创建 Mapper 代理对象
  3. 执行代理对象 Mapper 中的方法
  4. 事务(提交或者回滚)
  5. 关闭session

Mybatis 分页 分页插件的原理

Mybatis 只要有两种分页
1、 Mybatis 的假分页(使用RowBound 针对ResultSet 结果集执行内存分页)
2、 pagehelper 完成物理分页(实现原理 Mybatis 提供的插件接口实现自定义的插件)
在插件的拦截方法中拦截sql 重写sql 添加 相应物理分页的参数和语句

MyBatis 插件运行原理

主要可以针对 Paramenter(参数) RsultSet(结果集) statement(执行器对象) excutor (执行) 的handler

使用JDK 的动态代理

实现Mybatis 的interceptor接口并且复写 intercept方法 然后再给插件编写朱姐 制定要拦截哪一个接口的哪些方法、

SqlSessionFactory 与 SqlSessionFactoryBean 的区别 (SqlssionSessionBean 的作用?)

  • 在Spring 整合 MyBatis 的时候, 我们需要配置 SqlSessionFactoryBean 来充当SqlSessionFactory;
  • SqlSessionFactoryBean 实现了Spring 的FactoryBean 接口
  • 所以实际使用SqlSessionFactoryBean 的时候 实际上在Spring IOC 容器中的Bean 是sqlSessionFactory。

Spring

谈一下对Spring 的理解吧

首先Spring 是一个轻量级的JAVASE/JAVAEE 应用框架

Spring是模块化的。 我们可以只引入需要的部分
Spring 两大核心 IOC和AOP

Spring IOC 的理解?

IOC 的意思即是控制反转, 他是一种设计思想
在java开发中 ioc 可以将我们设计好的对象交给容器去管理控制, 而不是在对象内部直接控制, 对于Spring框架来说, 就是由Spring 来负责控制对象的生命周期和对象间的关系

谈一下 Spring AOP

AOP 成为面向切面编程, 是一种编程范式 是对面向对象编程的一种完善, AOP 解决了最大的问题 那就是解耦,

AOP的关注点是系统中的非核心— 权限 事务 安全 异常 日志等
例如事务就可以交由AOP 管理

SpringBean 的作用域

  • spring 提供 基本作用域
    singleton Spring 默认

prototype (多实例 struts2)

  • Spring 提供的web作用域
    request

session

global session

Spring 中 bean 的生命周期

Spring 事务的两种事务形式

Spring 事务的传播行为 (七种)

Spring 事务的隔离级别

过滤器与Spring 拦截器的区别

拦截器的实现原理是什么 简单说一下拦截器使用场景?

拦截器是基于Java 的反射机制实现的 , 更准确的说应该是JDK 实现的动态代理

日志 权限检查 性能监控 (有点类似 AOP 切面 但是功能上不如AOP 强大)

.过滤器和拦截器的区别:

①拦截器是基于java的反射机制的,而过滤器是基于函数回调。

②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

SpringMVC的理解

Spring 是构建在Spring 上的一个MVC 框架 他是Spring 框架的一个模块,
SpringMvc 是实现了请求驱动类型的轻量级web 框架
提供了对静态资源的支持
支持restful 风格的请求

SpringMVC的流程

主要组件
前端控制器(DispatcherServlet) 处理器适配器 处理器映射器 视图解析器

@RequestMapping 注解的作用

1 .相当于 RequestMappingHandlerMapping 和 RequestHandlerAdapter 结合
2. 可以使用value 属性将请求的url 映射到处理器的方法之上。
3. 默认可以接受所有类型的http 方法


SpringMVC 是怎么将url 映射到Controller 上的

主要通过处理器映射器
BeanNameUrlHandlerMapping
SimpleUrlHandlerMapping
RequstMappingHandlerMapping

SpringBoot 自动配置的原理

SpringBoot 借助Spring提供的java config 方式将bean 加载到容器中

SpringBoot 如何处理跨域

跨域其实有两种方式 1. cros 2 jsonp

  • jsonp

但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。
而JSONP就是通过script节点src调用跨域的请求。
当我们通过JSONP模式请求跨域资源时,服务器返回给客户端一段javascript代码,这段javascript代码自动调用客户端回调函数。
————————————————
版权声明:本文为CSDN博主「yuebinghaoyuan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yuebinghaoyuan/article/details/32706277

  • cros

其实原理都是 修改 Access-Control-Allow-Origin 请求头header
只是方式不同而已

  1. 实现WebMvcConfigurer 接口 的addCorsMappings() 方法
  2. 适应Spring web 自带的CorsFilter 处理 实现 Filter 重写 doFilter 方法
  3. 使用自定义的过滤器(或者拦截器)实现, 但是一定要配置到所有拦截器前面

Redis

简单介绍一下redis

redis 与 MemCached 的区别

redis 回收策略 过期机制的相关问题

Redis 缓存怎么与数据库保持一致(双写一致)

将删除缓存 修改数据库 读取缓存等的操作挤压到队列中 实现串行化即可

redis 集群与负载均衡策略

redis 集群机制中 有什么不足吗

redis 多数据库机制

redis 的事务? 不支持回滚

持久化方式(两种)应用场景

AOF 和 RDB


RPC MQ SpringCloud

定时任务的实现

corn 表达式的书写

消息队列用过什么?

WebService 简单说一下WSDL SOAP 都是什么?CXF

说一说对微服务框架的理解

SpringCloud 理解 (SpringCloud 都有哪些组件)

说一下 Dubbo 与SpringCloud 的区别

介绍一下 Dubbo

  • dubbo 是什么?
  • 为什么要用dubbo
  • 角色组成
  • dubbo 直连了解过吗?
  • dubbo 使用了什么协议 , 还有其他协议吗
  • 使用dubbo 的时候使用了什么注册中心?
  • Dubbo 的负载均衡策略? 默认是那种
  • Dubbo 的管理控制台能做什么?、
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值