最近一直在面试。面试了大约有10来家公司,有1000人以上的大公司,也有50左右的小公司。时间仓促没有准备充分,面试的机会虽然不少,可是面试时表现的通常。经过这10来场的面试,我对本身的知识体系薄弱环节有了较为清楚的认识。这里记录一些我在面试中遇到的比较常见的面试题。这只是其中的小小一部分。java
0. 数据库
很久没写代码了,SQL语句很生疏,致使我面试的时候简单的语法都忘了,吃了很大亏。这里推荐一篇大佬的博客。该博客中收录了常见的MySQL面试题和笔试题。SQL复习面试
1. 基本数据类型和引用数据类型的区别
问题分析:这个问题不是说有多难,只是咱们平时专一于代码逻辑,很容易忽视代码的底层原理。redis
示例答案:算法
- 基本数据类型在建立时,在栈上给其划分一块内存,将数值直接存储在栈上。
- 引用数据类型在被建立时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存中,而后由栈上的引用指向堆中的对象的地址。
这道题主要考察JVM中内存模型,这块须要重点理解。spring

JVM区域划分为:程序计数器,虚拟机栈,堆,方法区,本地方法栈五个区域。sql
①程序计数器: Java代码会被翻译成字节码,不一样字节码指令指挥计算机干不一样的事。程序计数器是用来记录每一个线程当前执行的指令的位置。由于程序能够是多线程的,因此每一个线程都有本身的程序计数器。数据库
②Java虚拟机栈:Java代码执行时,必定是线程执行某个方法中的代码。JVM中有一块区域用来保存每一个方法内的局部变量等数据,这个区域就是Java虚拟机栈。为何须要这个区域?由于每一个线程都会去执行各类方法的代码,方法内还会嵌套调用其余的方法,因此每一个线程都要有本身的Java虚拟机栈。编程
调用执行任何方法时,都会给方法建立栈帧,而后入栈。数组
③Java堆内存:用来存放Java中的建立的实例对象。好比Student对象。那么Java虚拟机栈中的变量student就会存放该对象的地址,或者说student指向了该对象。
④Java方法区:主要仍是存放咱们本身写的各类类相关的信息。
⑤本地方法栈:Java执行时会调用非Java代码,执行native方法,本地方法栈用来存放native方法的局部变量表等信息。
2. 检查时异常和运行时异常的区别
这个问题容易忽略。
Java中把全部的非正常状况分为两种:异常(Exception)和错误(Error),他们都继承Throwable父类。
Java的非正常状况能够分为检查异常
和非检查异常
。
其中Exception异常分为运行时异常
和非运行时异常
。

- 检查异常:
- 概念:就是编译器要求你必需要处理的异常。你的代码尚未运行时,编译器就会检查你的代码,对于可能出现的异常你必须使用try...catch...或者throws exception。
- 处理:①使用throws exception往上抛出,一直能够抛到Java虚拟机来处理。②使用try...catch...
- 范围:除了RuntimeException与其子类,错误Error之外的,差很少都是检查异常。
- 非检查异常:
- 概念:编译器不要求强制处置的异常,虽然可能出错,可是不会在编译时检查。
- 处理:①try..catch...②继续抛出③不处理
- 范围:RuntimeException与其子类,Error错误。
- 运行时异常:RuntimeException及其子类
- 非运行时异常:异常中除了RuntimeException及其子类之外都是非运行时异常。
3. Spring相关
若是你使用SSM框架,基本Spring一上来就问这几个问题,必须很是熟悉。
IOC:控制反转,传统的Java开发模式中,当须要一个对象时,咱们会本身使用new或者getInstance等直接或者间接调用构造方法建立一个对象。而在Spring中,Spring容器使用了工厂模式为咱们建立了所须要的对象,不须要咱们本身建立了,直接调用Spring提供的对象就能够了。
DI:依赖注入,Spring使用JavaBean对象的set方法或者带参数的构造方法为咱们在建立对象时将其属性自动设置所须要的值的过程,就是依赖注入的思想。
AOP面向切面编程:在面向对象编程思想中,咱们将事物纵向抽取成一个个的对象。而在面向切面编程中,咱们将一个个的对象某些相似的方面横向抽成一个切面,对这个切面进行一些如权限控制,事物管理,记录日志等公用操做处理的过程就是面向切面编程的思想。AOP的底层是动态代理,若是目标对象是接口采用JDK动态代理,若是是类采用Cglib方式实现动态代理。
动态代理的原理能够看看我以前写的一篇:动态代理
4. Java 中的 HashMap 的工做原理是什么?
面试官开始问你基础的时候,不少都从HashMap开始。
- Java 中的 HashMap 是以键值对(key-value)的形式存储元素的。HashMap 须要一个 hash 函数,它使用 hashCode()和 equals()方法来向集合/从集合添加和检索元素。当调用 put()方法的时候,HashMap 会计算 key 的 hash 值,而后把键值对存储在集合中合适的索引上。若是 key已经存在了,value 会被更新成新值。HashMap 的一些重要的特性是它的容量(capacity),负 载因子(load factor)和扩容极限(threshold resizing)。
5. HashMap 和 Hashtable 有什么区别?
HashMap 和 Hashtable 都实现了Map 接口,所以不少特性很是类似。可是,他们有如下不一样点:
- HashMap 容许键和值是 null,而Hashtable 不容许键或者值是 null。
- Hashtable 是同步的,而 HashMap 不是。所以,HashMap 更适合于单线程环境,而 Hashtable适合于多线程环境。
- HashMap 提供了可供应用迭代的键的集合,所以,HashMap 是快速失败的。另外一方面,Hashtable 提供了对键的列举(Enumeration)。通常认为 Hashtable 是一个遗留的类。
6. SQL优化
这里只是一些SQL优化的思路,远远不止这些。
- 使用JOIN的时候,应该用小的结果驱动大的结果『left join左边表结果尽可能小,若是有条件应该放到左边先处理』
- 尽可能把牵涉到多表联合查询拆分多个query,由于连表查询效率低,容易到以后锁表和阻塞。
- limit的基数比较大时使用between
- 尽可能避免在列上作运算,这样致使索引失效。
select * from admin where year(admin_time)>2014
优化为:
select * from admin where admin_time>'2014-01-01'
7. Redis
谈到Redis的话能够从如下几个方面简单说说。
8. RabbitMQ
明白MQ的概念、原理、使用场景。
- 概念:MQ全称是Message Queue,能够理解为消息队列的意思,简单来讲就是消息以管道的方式进行传递。RabbitMQ是一个实现了高级消息队列协议的消息队列服务,用Erlang语言的。
- 使用场景:好比秒杀系统中,当用户访问量很大时系统会提示咱们排队结算。这种排队结算就使用到了消息队列,生产者生产的消息放入通道中一个个地被消费,而不是某个时间内忽然出现大批量的查询新增把数据库给搞宕机了。因此RabbitMQ的做用是削峰填谷。
- 工做机制:
- 生产者:建立消息,发送消息到服务器
- 消费者:接受确认消息
- 代理:RabbitMQ自己,不产生消息,只是传递消息。
- 发送原理:首先要链接RabbitMQ。应用程序和RabbitMQ服务器之间会建立一个TCP链接,一旦TCP打开链接,而且经过了认证(认证就是尝试链接RabbitMQ服务器以前发送给服务器的链接信息,用户名和密码),应用程序和和Rabbit就建立了一条AMQP的信道。信道是建立在“真实”TCP上的虚拟链接,AMQP命令都是经过信道发送出去的,每一个信道都会有一个惟一的ID,不管是发布消息,订阅队列或者介绍消息都是经过信道完成的。
- 为何不经过TCP直接发送命令?
- 对于操做系统来讲建立和销毁TCP会话是很是昂贵的开销,假设高峰期每秒有成千上万条链接,每一个链接都要建立一条TCP会话,这就形成了TCP链接的巨大浪费,并且操做系统每秒能建立的TCP也是有限的,所以很快就会遇到系统瓶颈。
- 若是咱们每一个请求都使用一条TCP链接,既知足了性能的须要,又能确保每一个链接的私密性,这就是引入信道概念的缘由。
- 持久化工做原理:Rabbit会将你的持久化消息写入磁盘上的持久化日志文件,等消息被消费以后,Rabbit会把这条消息标识为等待垃圾回收
- RabbitMQ防止消息丢失?
- 客户端丢失消息确认:RabbitMQ引入了消息确认机制,当消息处理完成后,给Server端发送一个确认消息,来告诉服务端能够删除该消息了,若是链接断开的时候,Server端没有收到消费者发出的确认信息,则会把消息转发给其余保持在线的消费者。
9. Collection

- List接口:
- arrayList:底层实现基于动态数组,随机的访问查询比较快,插入,删除,修改比较慢,线程不安全。
- LinkedList 底层实现基于链表,因此查询慢,修改,删除,插入快,线程不安全。
- Vector :也是基于数组实现的,和arrayList的区别是线程安全,效率低。
- Set接口:不可重复
- HashSet: 使用哈希算法去重复, 效率高
- LinkedHashSet: HashSet的子类, 去重复而且保留存储顺序
- TreeSet: 能够用指定的比较方法进行排序