java面经汇总

牛客网 上面面经的摘取和汇总,以及我自己从网上补充的对应的答案。如有差错请见谅

1.自我介绍:略

2.Spring IOC和AOP概念(底层)

IOC即控制反转,指对组件对象的控制权的转移,从程序本身转移到外部容器,通过容器来实现对象的创建以及依赖关系的管理。spring就是IOC的一个容器。

好处:首先减轻了代码量,程序不需要new对象了,交给容器进行。其次实现了对象之间的解耦,降低了对象时间的依赖关系。

AOP即面向切面的编程,用途:就是将业务代码和公共服务代码解耦,使其可以独立开发和复用,让代码更加简单,简化开发流程。

AOP实现的基础就是IOC,只有实现了对象之间的解耦,才可能进而实现业务代码之间的解耦。

思想就是设计模式中的代理模式,通过代理/接口完成功能。具体实现的JDK的动态代理和CGLIB代理。

bean应该是Spring中最重要的东西了。也是容器创建的对象。

被称作bean的对象是构成应用程序的支柱也是由Spring IoC容器管理的.bean是一个被实例化,组装,并通过Spring IoC容器所管理的对象。这些bean是由用户容器提供的配置元数据创建的。

配置bean的方式有以下三种。

  • 基于XML的配置文件。
  • 基于注解的配置
  • 基于Java的配置

bean的作用域:https://blog.csdn.net/soonfly/article/details/69359772

1.singleton:单例模式,当spring创建applicationContext容器的时候,spring会欲初始化所有的该作用域实例,加上lazy-init就可以避免预处理;
2.prototype:(多例)原型模式,每次通过getBean获取该bean就会新产生一个实例,创建后spring将不再对其管理,即bean的生命周期由调用它的程序负责;
下面是在web项目下才用到的
3.request:搞web的大家都应该明白request的域了吧,就是每次请求都新产生一个实例,和prototype不同就是创建后,接下来的管理,spring依然在监听;
4.session:每次会话,同上;
5.global session:全局的web域,类似于servlet中的application;
好了,上面都说了spring的controller默认是单例,那很自然就是singleton了。

下面的知识点的链接 https://blog.csdn.net/qq_29945661/article/details/56915230

SpringMVC的工作流程?

  1. 用户发送请求至前端控制器DispatcherServlet

  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。

  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

  4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器

  5. 执行处理器(Controller,也叫后端控制器)。

  6. Controller执行完成返回ModelAndView

  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet

  8. DispatcherServlet将ModelAndView传给ViewResolver视图解析器

  9. ViewResolver解析后返回具体View

  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。

  11. DispatcherServlet响应用户

  1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
  2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
  3. Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

SSM的HTTP请求流程

Mybatis和hibernate区别

  1. Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
  2. Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
  3. Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
  1. mybatis配置
  2. SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
  3. mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
  4. 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
  5. 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
  6. mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
  7. Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
  8. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
  9. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

3.JAVA内存回收机制

java语言不要求程序员使用显示的方法来回收内存(垃圾),而是使用称为垃圾收集器的技术监视java程序的运行,当对象不再使用就自动释放该对象使用的内存。gc垃圾收集器是自动运行的,其会在程序运行时不时地检查各个对象的引用,并且回收无引用对象占用的内存。

4.Redis五种基本数据类型

字符串(String)哈希(Hash)列表(list)集合(sets)和有序集合(sorted sets)

5.数据库事务特征

ACID 原子性 一致性 隔离性 持久性

原子性:指事务的操作要么全部成功,要么全部失败回滚;

一致性:指事务必须使数据库从一个一致性状态变换到另一个一致性状态;

隔离性:多个用户并发访问数据库,每个用户的事务不会被其他事务干扰,相互隔离;

持久性:事务一旦被提交,对数据库的改变就是永久性的。

6.数据库内外连接区别

内连接是查询条件与连接条件匹配的数据行,返回两个表都存在的数据行,分为等值连接不等值连接和自然连接;

外链接是查询条件以某一个表为基准,返回另一个表的所有行;左连接,右连接和全连接,对于没有的数据返回NULL。

7.Docker映射端口参数

docker指令:docker run -p ip:hostPort:containerPort redis
使用-p参数 会分配宿主机的端口映射到虚拟机。

8.数据库隔离性解决的问题,不同的隔离级别,mysql默认的是什么

脏读,不可重复读,幻读

脏读:事务T1读取到了事务T2修改但是未提交的数据,之后事务T2回滚其操作,导致事务T1读到了脏数据;

不可重复读:事务T1读取到某一数据后,事务T2对其进行改变,当事务T1再次读取时得到了不一样的数据;

幻读:事务T1对某一个数据进行了修改,这时候事务T2在表中插入了某一个数据或者删除了某些数据,导致T1发现自己的修改并没有生效,产生幻觉。

  • 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
  • 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
  • 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
  • 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

MySQL:可重复读(Repeatable Read)
Oracle:读提交(Read Committed)
SQLServer:读提交(Read Committed)
DB2:读提交(Read Committed)
PostgreSQL:读提交(Read Committed)

9.B+树的介绍,红黑树介绍,B+为什么适合做数据库索引

B树就是二叉搜索树,其左右子树满足左子树小于根节点小于右子树,如果搜索二叉树接近平衡的话,那么查找效率就接近于二分法。另一个优点在于树的结构在内存上是不连续的,相对于连续存储的结构来说,其添加和删除节点对内存的改变将大大减小,甚至可能是常数级的开销;

B-树,B-树是一种多路搜索树。

1.定义任意非叶子结点最多只有M个儿子;且M>2;

2.根结点的儿子数为[2, M];

3.除根结点以外的非叶子结点的儿子数为[M/2, M];

4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)

5.非叶子结点的关键字个数=指向儿子的指针个数-1;

6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];

7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;

8.所有叶子结点位于同一层;

B-树

显然对于B-树每一次搜索都是在当前节点上进行二分查找,知道找到叶子节点为止,由于每层非叶子节点有着最小M/2的限制使得节点的利用比较合理,保证了最低的搜索性能为O(logn)同时B-树的搜索结果可能出现在中间非叶子节点上。

B+树是B-树的一种变体,也是一种多路搜索树,

1.其定义基本与B-树同,除了:

2.非叶子结点的子树指针与关键字个数相同;

3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);

5.为所有叶子结点增加一个链指针;

6.所有关键字都在叶子结点出现;

B+树

B+的特性:

1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

2.不可能在非叶子结点命中;

3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储
(关键字)数据的数据层;

4.更适合文件索引系统;MySQL就是使用B+树作为索引

  • B+-tree的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了.
  • 由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
    ps:我在知乎上看到有人是这样说的,我感觉说的也挺有道理的:
    他们认为数据库索引采用B+树的主要原因是:B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生.B+树只需要去遍历叶子节点就可以实现整棵树的遍历.而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作(或者说效率太低)

AVL树和红黑树

AVl树是带有平衡条件的二叉查找树,而红黑树则属带有弱平衡条件的二叉查找树,二者之间的区别在于:AVl更适合查找多,插入删除较少的操作,因为其插入和删除有可能破坏平衡条件,调整树的结构则是一件很耗时的事情;而红黑树相对而言插入和删除则会没有那么耗时,因此在插入删除操作多的情况下就使用红黑树。

AVL的要求: 左右子树高度差不超过1。

红黑树性质:

  • 每个节点非红即黑.
  • 根节点是黑的。
  • 每个叶节点(叶节点即树尾端NUL指针或NULL节点)都是黑的.
  • 如果一个节点是红的,那么它的两儿子都是黑的.
  • 对于任意节点而言,其到叶子点树NIL指针的每条路径都包含相同数目的黑节点.

结论,红黑树没有一条路径的长度是其他路径的长度的二倍,但是其高度要大于AVL树。

红黑树

10.HashMap 和 TreeMap(补充集合类)

先给一个java集合类的博客,很全很强大

先说一下Set和Map的区别:

Map是key-value结构,其中的key要求是不能重复,允许有一个null值,value则没有要求,可以重复也可以有多个null值。

Set则是普通的对象的集合,不能重复。

而HashMap和TreeMap均是实现了接口Map,各自的特性如下:

HashMap,是最常用的Map,其根据key的HashCode值进行存储value值,也可以根据key值直接获取它的value值,具有很快的访问速度。但是遍历的时候是完全随机的,只允许对多一个key值是null。

TreeMap是实现了SortMap接口,他可以把保存的key-value记录根据key值进行排序,默认的是升序自然排序,也可以指定排序的比较器,使用Iterator进行遍历的时候,得到的序列是排序的,key不允许为null。

补充一下List:

List接口的主要特点是有序,可以重复,最特殊的是List具有索引,以及一些列和索引相关的function,因此查询的速度很快。但是往List插入或者删除数据的时候,会影响其他数据的位置,因此速度会比较慢。

List Set和Queue均实现了Collection接口,Map则是与Collection无关。

ArrayList和LinkList:前者查询快,增删慢,适合多查找的操作,后者正好相反,查询慢,增删快,适合多增删的操作。(快慢只是二者相对而言)

底层实现:

HashMap使用了hash算法,TreeMap则是利用了红黑树的结构保证容器的对象是排序的。

11.JVM的内存模型,GC回收算法

GC回收算法:可达性算法,引用计数算法

引用计数法:存在于早期的gc中,给对象添加一个引用计数器,有一个地方引用计数器就加一,引用失效是计数器就减一;当引用计数器为0的时候就代表对象是不可能被使用了,可以被垃圾收集器收集。当一个对象被gc收集时,它引用的任何对象实例的引用计数器减一。

缺点:无法检测出循环循环引用。

可达性分析算法,通过一列GC root的对象为起点,从这些起点开始向下搜索,搜索到的路径称为引用链(Reference Chain),当一个对象到GC Roots 没有任何引用链相连的时候,则证明此对象是不可用的。即为可回收对象。

12.java内存中的堆和栈

函数中的一些基本类型变量和对象的引用变量都是在函数的栈内存中分配的。

栈的数据是可以共享的。

对内存则是存放new创建的对象和数组。

栈内的变量取值等于对象在堆内的首地址,这样栈内的变量就成了引用变量。

堆内的数组和对象在没有引用变量指向它的时候就会变成垃圾,会被GC在一个不缺定的时间回收释放掉。

13.网络方面(放在一起)

  1. http解析

http与https的区别在于http是明文传输,不具有安全性,因此引入https,将http与ssl加密结合在一起

  1. UDPTCP区别以及三次握手

UDP是不可靠的尽力而为的传输,其是无连接状态,不保证每个包正确到达接收端,只能是尽力而为的传输。

而TCP则是面向连接的可靠传输,其通过三次握手建立连接,且每一个包都会有确认机制,保证每个包都能正确的到达接收端。

三次握手是双向通道建立的前提:

第一次B请求建立连接,发送自己的初始信号seq,

第二次S响应连接,并且回复自己的初始信号seq以及对A的同步信号的确认信号ACK

第三次B对S的响应进行确认,之后开始传输。

如果是两次握手,没有第三次握手,则一旦有无效的第一次握手到达Server服务器端,则服务器则会进入准备阶段,一直等待接收或者发送数据。造成资源浪费。

次数更多的握手没有必要,因为那只会得出同一个结论。浪费传输资源。

  1. OSI7层协议TCP/IP五层协议
  2. GET方法 和POST方法

语义上的区别,GET是用来获取数据。POST是用来提交数据,并且对其进行处理。

具体的实现区别如下:

GET POST
后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
书签 可收藏为书签 不可收藏为书签
缓存 能被缓存 不能缓存
编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。
历史 参数保留在浏览器历史中。 参数不会保存在浏览器历史中。
对数据长度的限制 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 无限制。
对数据类型的限制 只允许 ASCII 字符。 没有限制。也允许二进制数据。
安全性 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET ! POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。
可见性 数据在 URL 中对所有人都是可见的。 数据不会显示在 URL 中。

POST不是幂等的,会对服务器数据进行修改。

GET是幂等的,不会对服务器数据进行修改。

14.锁(都放在一起)

先给一个java锁的链接,说的很全

公平锁和非公平锁指多个线程获得锁的顺序是否和它们申请锁的顺序一致,公平所不会造成线程饥饿但是吞吐量不高,非公平锁根据优先级分配锁,吞吐量高但是容易造成饥饿现象。

可重入锁,又称递归锁,指一个线程在外层方法调用锁的时候同时在进入内层方法会自动获取锁。

独享锁/共享锁,是指一个锁可以被一个线程持有还是被多个线程持有。

互斥锁/读写锁,就是独享锁和共享锁的意思,具体来说就是ReentrantLock和ReadWriteLock。

乐观锁和悲观锁,这是从并发的角度看待的。悲观锁认为,如果对一个数据进行并发操作,就一定会发生修改,因此一定要加锁。而乐观锁认为,对同一个数据进行并发操作,是不会发生修改的,在更新数据的时候,会采取尝试更新,不断更新的方式进行。认为不加锁的操作是可以的。

分段锁其实是一种锁的设计,并不是具体的一种锁,对于ConcurrentHashMap而言,其并发的实现就是通过分段锁的形式来实现高效的并发操作。
我们以ConcurrentHashMap来说一下分段锁的含义以及设计思想,ConcurrentHashMap中的分段锁称为Segment,它即类似于HashMap(JDK7与JDK8中HashMap的实现)的结构,即内部拥有一个Entry数组,数组中的每个元素又是一个链表;同时又是一个ReentrantLock(Segment继承了ReentrantLock)。
当需要put元素的时候,并不是对整个hashmap进行加锁,而是先通过hashcode来知道他要放在那一个分段中,然后对这个分段进行加锁,所以当多线程put的时候,只要不是放在一个分段中,就实现了真正的并行的插入。
但是,在统计size的时候,可就是获取hashmap全局信息的时候,就需要获取所有的分段锁才能统计。
分段锁的设计目的是细化锁的粒度,当操作不需要更新整个数组的时候,就仅仅针对数组中的一项进行加锁操作。

自旋锁,就是在尝试获取的进程不会立即阻塞(获取失败),而是再用循环的方式不断的尝试获取锁,这样的好处的减少了线程上限文的切换消耗,但是会增加CPU消耗。

15.Redis 与 Memcached

Redis是一个速度极快的非关系数据库,也就是我们所说的NoSQL数据库(non-relational database),它可以存储键(key)与5种不同类型的值(value)之间的映射(mapping),可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片来扩展性能,并且它还提供了多种语言的API。

Memcached它是基于内存工作的键-值存储型的数据库。广泛应用于互联网网站中,作为应用于数据库交互的中间层、即缓存。大大提高网站的访问速度。

二者的区别或者说各自的特定:

Redis有五种数据结构,String Hash List Set Sorted Set。Redis支持持久化,即可以将内存的数据转移到硬盘中保存。支持数据备份master-slave模式的数据备份。网络IO模型上使用单线程的IO复用模型,对于仅有IO操作的时候,单线程速度优势会发挥到最大,但是一旦进行其他计算功能,就会影响整体吞吐量。因为cpu计算的时候,IO是被阻塞的。相对于Memcached只能在客户端进行分布式存储,Redis更偏向在服务器端构建分布式存储。

Memcached:只有key-value数据结构,就是对应String结构。而且只支持内存上的临时数据库,不支持持久化的操作。网络IO模型上,Memcached使用的多线程非阻塞IO复用模型。多线程可以发挥CPU多核的作用但是会引入锁和缓存一致性的问题。会带来性能损耗。Memcached本身不支持分布式,只能在客户端通过想一致性哈希这样的分布式算法来实现Memcached的分布式存储(没懂)

redis 优点

丰富的数据类型: String, List, Set, Sorted Set, Hash
支持两种数据持久化方式 :RDB持久化 (快照)和AOF持久化Append Only file(追加)

http://www.cnblogs.com/Anker/p/6099705.html

支持主从复制

redis的集群功能(分布式 ):Redis Cluster 参考链接:https://blog.csdn.net/dc_726/article/details/48552531

  1. 性能:这是Redis赖以生存的看家本领,增加集群功能后当然不能对性能产生太大影响,所以Redis采取了P2P而非Proxy方式、异步复制、客户端重定向等设计,而牺牲了部分的一致性、使用性。
  2. 水平扩展:集群的最重要能力当然是扩展,文档中称可以线性扩展到1000结点。
  3. 可用性:在Cluster推出之前,可用性要靠Sentinel保证。有了集群之后也自动具有了Sentinel的监控和自动Failover能力。(某个节点挂了,依旧可以使用)

宕机与数据迁移:

16.集合类源码

图片链接:http://www.cnblogs.com/xwdreamer/archive/2012/05/30/2526822.html

集合类框架图

显然,点线如 Iteraror Collection等是接口,划线 AbstractCollection等是抽象类,实线则是类。

HashMap:

加载因子,扩容,拉链检测等

加载因子越大,空间利用率高,但是造成冲突的概率也越高;加载因子越小,空间利用率低,但时产生冲突的概率也低。

当元素的个数大于加载因子和容量的乘积时就要对hashmap进行扩容。

扩容:首先HashMap要求Hash数组的长度必须是2的倍数,求位置的方式就为【h&(length-1)】h就是hashcode,length就是数组的长度。扩容后的长度就是之前数组长度的二倍。这样在做与&操作的时候,原来的length-1和新的length-1其实就差了一位1,这样扩容前后的位置就不会变化,多的最高位0&1还是0。(不一定了)

拉链法:针对hashcode冲突的处理,使用拉链法,即不同的key值经过哈希处理之后得到相同的hashcode,那么对应的数组的位置就是一样的,后来的key发现应该放置的位置被先前的数据占据了,此时就将hashcode相同的数据形成一个链表,新来的数据放在链表头。对应查找的时候就要调用key.equal()算法去比较链表中的每一个value,当链表过长的时候自动转化为树结构(红黑树)

我们现在可以回答开始的几个问题,加深对HashMap的理解:

1. 什么时候会使用HashMap?他有什么特点?
是基于Map接口的实现,存储键值对时,它可以接收null的键值,是非同步的,HashMap存储着Entry(hash, key, value, next)对象。

2. 你知道HashMap的工作原理吗?
通过hash的方法,通过put和get存储和获取对象。存储对象时,我们将K/V传给put方法时,它调用hashCode计算hash从而得到bucket位置,进一步存储,HashMap会根据当前bucket的占用情况自动调整容量(超过Load Facotr则resize为原来的2倍)。获取对象时,我们将K传给get,它调用hashCode计算hash从而得到bucket位置,并进一步调用equals()方法确定键值对。如果发生碰撞的时候,Hashmap通过链表将产生碰撞冲突的元素组织起来,在Java 8中,如果一个bucket中碰撞冲突的元素超过某个限制(默认是8),则使用红黑树来替换链表,从而提高速度。

3. 你知道get和put的原理吗?equals()和hashCode()的都有什么作用?
通过对key的hashCode()进行hashing,并计算下标( n-1 & hash),从而获得buckets的位置。如果产生碰撞,则利用key.equals()方法去链表或树中去查找对应的节点

4. 你知道hash的实现吗?为什么要这样实现?
在Java 1.8的实现中,是通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16),主要是从速度、功效、质量来考虑的,这么做可以在bucket的n比较小的时候,也能保证考虑到高低bit都参与到hash的计算中,同时不会有太大的开销。

5. 如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办?
如果超过了负载因子(默认0.75),则会重新resize一个原来长度两倍的HashMap,并且重新调用hash方法。

以Entry[]数组实现的哈希桶数组,用Key的哈希值取模桶数组的大小可得到数组下标。

插入元素时,如果两条Key落在同一个桶(比如哈希值1和17取模16后都属于第一个哈希桶),我们称之为哈希冲突。

JDK的做法是链表法,Entry用一个next属性实现多个Entry以单向链表存放。查找哈希值为17的key时,先定位到哈希桶,然后链表遍历桶里所有元素,逐个比较其Hash值然后key值。

在JDK8里,新增默认为8的阈值,当一个桶里的Entry超过閥值,就不以单向链表而以红黑树来存放以加快Key的查找速度。

当然,最好还是桶里只有一个元素,不用去比较。所以默认当Entry数量达到桶数量的75%时,哈希冲突已比较严重,就会成倍扩容桶数组,并重新分配所有原来的Entry。扩容成本不低,所以也最好有个预估值。

取模用与操作(hash & (arrayLength-1))会比较快,所以数组的大小永远是2的N次方, 你随便给一个初始值比如17会转为32。默认第一次放入元素时的初始值是16。

iterator()时顺着哈希桶数组来遍历,看起来是个乱序

Hashtable 和 HashMap的区别:

他们均实现了Map接口,但是之间有所差别:线程安全性,同步(synchronization),以及速度。

Hashtable是同步的,因此也是线程安全的,所以单线程下速度较慢,但是可以被多个线程共享。

HashMap非同步,因此速度较快。Java5 中提供了ConcurrentHashMap,它是Hashtable的替代,比Hashtable的扩展性要。

ConcurrentHashMap:

Hashtable是所有线程使用同一把锁,而ConcurrentHashMap则是将容器里的一部分数据分配一把锁,这样不同线程访问不同数据的时候就不存在竞争。从而可以提高并发效率。

ConcurrentHashMap是由Segment和HashEntry两个数组结构组成的。Segment是一种可重入锁ReentrantLock,在ConcurrentHashMap中扮演着锁的角色。

17.死锁

考研的知识。。。

死锁产生的条件:

互斥 占有并等待 不可剥夺 循环等待

因此死锁的预防就是从上面后三个条件出发:

破坏占有并等待(令进程一次清请求所有资源),破坏不可剥夺条件(如果要申请新的资源,必须先释放资源),破坏循环等待条件(令资源的申请具有一定顺序)。

死锁避免:如果该进程的请求资源后会导致死锁,拒绝启动该进程;如果一个资源被分配出去后会导致下一步的死锁,就拒绝分配该资源。

18.innodb等数据库引擎的特点(MyISAM,InnoDB,ISAM)

InnoDB和MyISAM区别或者说各自的特点:

InnoDB:可靠性高 ,或者要求事务, 效率低一些。提供了数据可对ACID事务的支持,并且实现了SQL的四种隔离等级,还提供了行级锁和外键约束,其设计目的是处理大容量数据库系统。不保存表的行数,因此select count(*)from table 时需要扫描全表。并发情况较高时该数据库效率会提高。如果一个SQL语句不能确定扫描的范围,就要锁全表。

MyISAM:查找效率很高。但是不具备事务支持,是MySQL的默认引擎。也不支持行级锁和外检。insert和update时需要锁定全表,效率会低一些。但是记录了表的行数,select count(*)from table 直接读取保存好的值不用扫描全表。读操作远远多于写操作且不需要事务支持的情况,可以选择MyISAM。

待续。。。。

19.操作系统等

进程和线程的区别:

进程是系统调度分配资源的最小的单位,一个进程可以有多个线程。而线程则是cpu调度和分派的最小单位,多个线程共享进程的内存资源

20.java中的同步异步知识点/并发.

见另一篇博客

21.equals,hashcode “==” 堆栈内存

这个知识点单独拿出来吧。

首先equals方法来自Object超类,是通过判断两个对象具有两个相同的引用地址(堆内的地址),来判断是否相等。使用的也是“==”,结果是一样的。

比如对于 int a = 3; int b = 3;他们均是栈内存中找有没有3这个值,然后将栈内存中的a和b均引向栈内存中的3

这样二者指向的地址就是一样的,a == b就是true。

对于String a = “123”和String b = “123”也是同理。

但是对于new出来的对象,String a = new String(“123”); 和String b = new String(“123”);两次new之后再对内存中的地址是不一样的,尽管他们的值一样。因此使用原始的equals方法和==得到的结果均是false。

对于这种现象,String类里面的equals就重写的equals方法,将逻辑变为判断字符串的值是否相等,而不是内存地址。因此使用a.equals(b);返回的就是true。

回到HashMap中,先给出结论:重写equals()的同时还得重写hashCode(),首先这两个方法都在Object类中声明,使用的均是内存地址,即new的两个对象,其equals()和hashcode()的值均是不同的。但是一旦重写了equals的方法而不重写hashcode()方法就会出现两个equals()的对象的hashcode()会不同,因为默认使用内存地址进行哈希。

在Java API文档中关于hashCode方法有以下几点规定(原文来自java深入解析一书)。

  • 在java应用程序执行期间,如果在equals方法比较中所用的信息没有被修改,那么在同一个对象上多次调用hashCode方法时必须一致地返回相同的整数。如果多次执行同一个应用时,不要求该整数必须相同。
  • 如果两个对象通过调用equals方法是相等的,那么这两个对象调用hashCode方法必须返回相同的整数。
  • 如果两个对象通过调用equals方法是不相等的,不要求这两个对象调用hashCode方法必须返回不同的整数。但是程序员应该意识到对不同的对象产生不同的hash值可以提供哈希表的性能。

显然不重写违反了第二条原则。

最后说一下重写equals()的原则

1. 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。

2. 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。

3. 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。

4. 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。

5. 对于任何非空引用值 x,x.equals(null) 都应返回 false。

22.数据库的范式

关系数据库中有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。

一般来说数据库只要满足第三范式就可以了。

范式具有包含关系,一个数据库如果符合第二范式那么 一定符合第一范式。

范式越高,数据库的冗余度越小。

第一范式(1NF):属性不可分(1NF是对属性的原子性约束,要求属性具有原子性,不可再分解)

第二范式(2NF):符合1NF,并且非主属性完全依赖于码。(2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性,更通俗说有主键ID)

第三范式(3NF):符合2NF,并且,消除传递依赖。(3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余)

BCNF:符合3NF,并且,主属性不依赖于主属性。

23.排序相关

快排、堆排、归并排序、大量数据排序

快排代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
   public static void quicksort(int n[], int left, int right) {
sort(n,left,right);
}
private static void sort (int[] n, int l, int r) {
if (l >= r)
return;
int p = partition(n,l,r);
sort(n,l,p-1);
sort(n,p+1;r);
}
private static int partition(int []n, int l, int r) {
if (l >= r) // 可有可无,因为在外面递归的时候已经有停止条件了
return;
int i = l, j = r; //可有可无,直接用l和r也行
int pivot = n[i]; //保存标尺的值
while (i < j) {
while (n[j] >= pivot && j > i)
j--;
if (j > i)
n[i++] = n[j];
while (n[i] < pivot && i < j)
i++;
if (i < j)
n[j--] = n[i];
}
n[i] = pivot;
return i;
}

24.Linux常见命令

25.ER图以及SQL语句

26.Tomcat以及与其他服务器框架的区别

内容大多来自知乎链接:https://www.zhihu.com/question/32212996/answer/87524617

HTTP服务器本质上也是一种应用程序——它通常运行在服务器之上,绑定服务器的IP地址并监听某一个tcp端口来接收并处理HTTP请求,这样客户端(一般来说是IE, Firefox,Chrome这样的浏览器)就能够通过HTTP协议来获取服务器上的网页(HTML格式)、文档(PDF格式)、音频(MP4格式)、视频(MOV格式)等等资源。下图描述的就是这一过程:

不仅仅是Apache HTTP Server 和Nginx,绝大所编程语言所包含的类库中也都实现了检点HTTP服务器方便开发者使用。

使用这些类库能够非常容易的运行一个HTTP服务器,它们都能够通过绑定IP地址并监听tcp端口来提供HTTP服务。

通常所说的Apache,指的应该是Apache软件基金会下的一个项目——Apache HTTP Server Project;Nginx同样也是一款开源的HTTP服务器软件(当然它也可以作为邮件代理服务器、通用的TCP代理服务器)。

Apache Tomcat则是指Apache基金会下的另外一个项目,与Apache HTTP Server相比,Tomcat能够动态的生成资源并返回到客户端。Apache HTTP Server 和Nginx都能讲一个文本文件内容通过Http协议返回给客户端。但是这个文本文件内容是固定的,也就是静态资源。

Apache HTTP Server和Nginx本身不支持生成动态页面,但它们可以通过其他模块来支持(例如通过Shell、PHP、Python脚本程序来动态生成内容)。

如果想要使用Java程序来动态生成资源内容,使用这一类HTTP服务器很难做到。Java Servlet技术以及衍生的Java Server Pages技术可以让Java程序也具有处理HTTP请求并且返回内容(由程序动态控制)的能力,Tomcat正是支持运行Servlet/JSP应用程序的容器(Container):

  • 管理Servlet程序的生命周期
  • 将URL映射到指定的Servlet进行处理
  • 与Servlet程序合作处理HTTP请求——根据HTTP请求生成HttpServletResponse对象并传递给Servlet进行处理,将Servlet中的HttpServletResponse对象生成的内容返回给浏览器

虽然Tomcat也可以认为是HTTP服务器,但通常它仍然会和Nginx配合在一起使用:

  • 动静态资动态资源的请求交给Tomcat,而静态资源的请求(例如图片、视频、CSS、JavaScript文件等)则直接由Nginx返回到浏览器,这样能大大减轻Tomcat的压力。
  • 负载均衡,当业务压力增大时,可能一个Tomcat的实例不足以处理,那么这时可以启动多个Tomcat实例进行水平扩展,而Nginx的负载均衡功能可以把请求通过算法分发到各个不同的实例进行处理

以上 HTTP Server更关心的功能是HTTp协以层面的传输和访问控制,比如Nginx就有代理、负载均衡功能。其功能本质上就是将服务器上的内容分发给客户端。但是分发的内容是什么,怎么形成(动态资源)。这就是应用服务器的任务了,Tomcat就是干这个的,它本质上是一个JSP/Sevlet的一个容器,提供相关的标准类库。只不过将HTTP服务器分发功能集成在一起罢了。Tomcat仅仅支持java,其他语言也有各自的平台(应用服务器)。

27.JVM相关

JVM面试题的链接https://www.jianshu.com/p/54eb60cfa7bd

从javac编译4阶段:词法,语法语义,生成,到类加载过程

双亲委派:加载,验证,准备,解析,实例化

实例化先谈堆分区,再说JVM内存结构,然后到GC,GC算法,触发条件,晋升,YGC,CMS过程实现,可达性分析等等

Javac编译过程

Javac编译过程大致分为4个过程,分别是:

  1. 词法分析
  2. 语法分析
  3. 语义分析
  4. 代码生成

类加载过程

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。它们开始的顺序如下图所示:

img

28.git相关

git相关的命令。

git rebase什么意思

三个区域, 工作区 暂存区 和 版本库(远程仓库/历史区域)

29.设计模式(代理模式,观察者模式,策略模式等)

工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。是一种创建类的模式

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

观察者模式是基于对象的状态变化和观察者的通讯,以便他们作出相应的操作。简单的例子就是一个天气系统,当天气变化时必须在展示给公众的视图中进行反映。这个视图对象是一个主体,而不同的视图是观察者。可以在这篇文章中看到Java观察者模式的完整例子。

MVC设计模式:MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。

代理模式:为其他对象提供一种代理以控制对这个对象的访问。

代理模式又分为静态代理动态代理。静态代理是由程序猿创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理是在程序运行时,通过运用反射机制动态的创建而成。

策略模式:完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务。

30.java反射机制

Java反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)获得任何一个类的字节码。包括接口、变量、方法等信息。还可以让我们在运行期实例化对象,通过调用get/set方法获取变量的值。

Java的反射机制是在编译时并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用的是在编译期并不知道的类。这样的编译特点就是java反射。

实际使用:通过对象获知 类的信息。可以不用new进行实例化。在jvm运行代码的时候,不用修改源码,就实现修改类的效果。(使用配置文件)

31.对称加密非对称加密

对称加密:加密和解密都使用同一个秘钥,加密的秘钥通常大小较小,但是加密和解密的速度较快,效率很高。

非对称加密:加密和解密使用不同的秘钥,加密使用公开的公钥,可以对所有人公开,但是只有持有私钥的解密人才能解开信息。安全性大大提高。但是代价就是速度慢得多。

通常使用非对称加密对对称加密的公钥进行加密,然后在用对称加密的秘钥对信息进行解密。

目标:(摘自某招聘信息)

具备扎实的Java基础知识和良好的编码风格,深入理解Java虚拟机,反射机制以及常用的设计模式。
熟悉MVC设计模式,掌握SpringMVC、Mybatis等主流MVC框架的工作原理。
熟练使用MySQL,至少熟悉Redis、Memcached、Kafka、Dubbo等主流中间件框架中的二种,及其原理。
熟悉Nginx、Tomcat、Netty等应用服务框架,熟练使用Linux/UNIX等服务器的常用命令。
熟练使用常见的IDE工具,如Idea、eclipse、maven、gradle、git等。

熟悉Web JSP,Servlet,Java Bean,JMS,EJB,Jdbc开发,熟悉J2EE规范;
熟练使用Spring,Struts,iBatis框架,阅读过源码优先;
熟悉基于数据库的设计和开发,熟练掌握mysql,oracle,sqlserver数据库中的一种;
熟悉hbase、mogonDB等非关系型数据库使用;
熟悉memcache、redis等缓存技术使用;
熟悉Linux操作系统和调优,熟练掌握eclipse,idea开发环境;
熟悉Web前端技术html, js

附 ,牛客网上的面经:

2.ArrayList,LinkedList区别,适用场景。

  • 答:前者基于动态数组,后者基于链表。因此随机访问前者优,而增删操作后者优

    3.HashMap为什么重新计算hash值

  • 答:原始的resize的算法使将表扩容之后,因此原始冲突的数据现在可能分配在新扩容出来的位置,因此要重新计算hash。

  • 但是现在1.8是将表增加为原来的二倍,因此只需要计算多出来一位的是0还是1即可,然后概率还是对半分,可以使原本冲突的节点重新均匀分开。

    4.谈谈乐观锁

  • 答:乐观锁就是在写代码过程中吗,认为这一段代码不加锁也可以正常运行,不会出问题。最后出问题也会有对应的方法来处理。

    5.说说CountDownLatch

  • 答:CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

    6.谈一下Spring IoC,IoC怎么创建的单例对象

  • 只要不在xml文件中写 scope = prototype ,就是单例对象。

    7.Spring AOP

  • 将其余或者公共业务封装成一个切面,注入到目标业务代码中。

  • 代理模式具体就是在IOC容器初始化bean的时候将其拦截,创建代理将其替换。

    8.说一下Mybatis的事务…MySQL的事务

  • 单独使用时候使用 SqlSession处理事务

  • 和Spring集成之后, 使用Spring的事务管理器
  • mySQL必须使用innodb引擎才能处理事务。
  • 通过三中操作,开始 回滚和确认来实现事务,对一组操作实现ACID

    9.怎么进行索引调优的

  • mySQL是使用B+树进行索引调优的,调优的方式:

10.MySQL索引的数据结构,使用B 树的原因

11.创建线程在内存模型中分配的位置
12.讲一下Full GC
13.垃圾回收算法

  • 引用计数算法和可达性分析算法

    14.Cookie、Session

  • Cookie 在浏览器 Session 在服务器端, Session 依赖于session id 而这个id是在cookie中的。

  • session是用来跟踪会话的, 而cookie不仅可以跟踪回话 还可以保存用户喜好等信息。

    15.URL的请求流程

  • 域名解析 —>

  • 发起TCP的3次握手 —>
  • 建立TCP连接后发起http请求 —>
  • 服务器响应http请求,浏览器得到html代码 —>
  • 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) —>
  • 浏览器对页面进行渲染呈现给用户

1.自我介绍
2.熟悉内存模型,说一下内存划分

3.堆怎么划分

4.新生代怎么划分
5.创建对象怎么保证线程安全
6.创建对象怎么分配内存
7.说说STW
8.Minor GC会STW吗
9.CMS垃圾回收器、G1垃圾回收器
10.虚拟机在加载类静态变量的时候是线程安全的吗,为什么、怎么实现的
11.HashMap和HashTable的区别
12.HashMap初始数组长度为16(为2的倍数)的原因
13.sleep和wait方法的区别
14.Java线程池
15.IoC的实现原理
16.IoC生成实例用的技术
17.AOP的实现原理
18.Mybatis的一二级缓存
19.git操作指令
20.MyISAM和InnoDB的区别
21.InnoDB的索引
22.redo log和undo log,redo log怎么保证持久性和原子性


1、spring的理解。

2、Redis缓存的应用

3、http解析的全过程

4、Java中的锁

5、Hashmap和concurrenthashMap源码

6、死锁的避免

7、osi网络七层协议

8、编程题:找出一个最长子序列,是子序列的和为k的整数倍。


1、AOP和IOC。

3、Redis缓存的应用

4、数据库底层索引数据结构和原理。

5、Hashmap和concurrenthashMap理解

6、SpringMVC执行过程

7、编程题:找出M的数的从小到大前N的数。

8、sql语句的编写。

9、JVM运行时内存模型。

10、工厂模式和代理模式。


1、spring用到的设计模式。

2、项目相关难点

3、Redis缓存的应用、消息队列、redis持久化策略。

4、数据库底层索引数据结构和原理。

5、编程题:无顺序数组的最大差(intdex1>index2)。

6、sql语句的编写。

7、门禁系统数据库设计.

8、工厂模式和代理模式。

9、cup负荷高时的排查方法。

10、自己设计数据库连接池时需要的参数。

11、linux命令:查看cpu、查看文件列表。 还有磁盘冗余阵列(RAID)模型

1.自我介绍,嘿嘿,刚开始有点慌,不知道自己在说啥!
2.TCP/IP三次握手和四次挥手,各个状态也讲讲及为啥要三次握手和四次挥手
2.JVM运行时数据区详细介绍
2.JVM各个区域发生异常场景和原因,举例说说
2.常见的垃圾收集器介绍下
3.Spring讲讲,并且说说底层实现原理(IOC+AOP)和运行流程
3.详细说说JDK动态代理和CGLIB动态代理,主要说说底层实现原理和区别
3.SpringMVC运行流程和底层原理
4.HashMap和CurrentHashMap区别和底层原理
4.ArrayList源码讲讲
4.LinkedList源码讲讲及和ArrayList的区别
5.索引的底层原理和B+树的特点和优势
5.索引的失效介绍下
5.Explain你咋用的,详细讲讲
5.数据库引擎讲下
6.Git常用命令讲讲
6.NIO,BIO,AIO区别和优缺点
7.Redis的数据结构和使用场景讲讲
8.项目的介绍
8.你项目中用Redis的目的
8.Dubbo的底层原理和优点
8.ActiveMQ的底层原理和优点,为啥使用
8.你的分布式session咋弄得,有其他方法吗
8.你的Solr集群咋搭的,页面静态化技术实现讲讲

1.自我介绍
2.CurrentHashMap的特点和实现原理(按源码讲)
2.给我详细讲讲红黑树
2.ReentrantLock的底层实现机制(讲源码)
3.SpringMVC的底层原理和运行机制
3.SpringMVC的URL映射原理
3.SpringIOC底层原理
4.TCP粘包讲讲
5.硬连接和软连接的底层原理
5.你所知道的Linux命令随便说
5.VIM常用命令
6.你知道的设计模式特点,优劣,场景应用随便扯
7.线程池工作原理和详细参数
7.如果是你,你会怎么设计一个线程池
8.WebSocket你项目中怎么使用的及运行原理
8.WebSocket穿墙问题你怎么处理
8.JSOUP的底层原理和优势
8.Redis集群搭建过程和主从复制原理
8.你的Dubbo怎么用的及软负载均衡算法讲讲原理
8.你是视频模块怎么做的
8.MyCAT分片规则和原理
8.Hadoop的HDFS的优劣
9.你有什么想问的

1、自我介绍
2、TCP与UDP的区别

​ 3、TCP三次握手说一下(把流程说一遍,这里以为会继续问为什么不是两次或者四次,结果没有)

​ 4、看你项目用到线程池,说一下线程池工作原理,任务拒接策略有哪几种
5、进程和线程的区别
6、ArrayList与LinkedList的区别

​ 7、线程安全与非线程安全集合说一下,底层怎么实现的(hashmap,concurrenthashmap)
8、Java内存模型,方法区存什么

​ 9、数据库事务隔离级别说一下

​ 10、synchronized和lock区别,可重入锁与非可重入锁的区别

​ 11、看你的项目用了悲观锁和乐观锁,说一下区别

​ 12、算法题:圆圈中最后剩下的数字

​ 二面 (部门主管):
1、说一下Spring的IOC和AOP,底层什么原理

​ 2、动态代理有几种,Jdk与Cglib区别
3、数据库三大范式
4、左连接和右连接说一下,内连接呢
5、数据库索引有几种

​ 6、数据库引擎你认识几种,innodb 和myisam 区别,你的项目用到哪个引擎
7、若hashcode方法永远返回1会产生什么结果
8、Error与RuntimeException的区别
9、引用计数法与GC Root可达性分析法区别
10、双亲委派机制说一下

​ 11、算法题:找出一个数组中第100个小的数字(堆思想解决)

​ 三面&四面 (这里合在一起写了,分别是部门A总监与B总监,本以为三面完了就是HR面,结果隔天B总监打过来说补一轮技术面~~三面和四面更多的是问项目,基础问得不多):

​ 1、volatile关键字作用
2、看你项目用到策略模式和工厂模式,说一下区别
3、模板方法模式
4、开闭原则懂吗,说一下

​ 5、NIO说一下你的理解

​ 6、AtomicInteger底层原理

​ 7、CAS机制会出现什么问题

​ 8、还用过并发包哪些类
9、你实习的本地缓存过期策略怎么设置,一致性怎么保证
10、分布式理论懂多少,说一下(这里我说了CAP,Base,paxos)

​ 11、分布式事务有了解吗
12、RabbitMQ消息队列丢失消息,重复消费问题

美团一面:

数据库索引

数据库事务

设计数据库 ER图

内部类

封装继承多态 中的多态

设计模式

对称和非对称加密

git

https加密过程

session

ajax

异常

快慢指针

链表第k大的数

java和javascript的区别,和php的区别

springMVC工作流程

MVC设计模式原理

MyISAM 和InnoDB

前者是表锁 后者是行锁

前者是索引在内存 数据在硬盘是分开的,因此直接通过索引查询得到数据IO较少,后者的IO较多

前者不支持外键