在这里记录总结一下第一次面试经历。
前段时间投的简历,这两天准备期末考试(怂,就靠这两冲刺那。。),把面试的事搁置了,昨天下午HR突然打电话来直接要求技术面试,然后我只能说不方便了。。。明天十一点可以吗。。。可以!
温馨提示:面试还是得早点就做好准备的(我之前准备了,利用这几个小时好温习一下)。
不说那么多废话了,开始面试问题吧。
啦啦啦啦。。。就介绍完了,建议尽量提前写一下自我介绍的稿子。
list接口:存储不唯一的(可重复),有序的元素。
set接口:存储不可重复元素,无序的元素。
map接口:使用键值对进行存储元素。
常用的有LinkedList和ArrayList两个,(当时没记起来Vector和Stack)
(当时紧张到说了句ArrayList。。。蠢哭自己了,连忙道歉)
是LinkedList,从它的底层数据结构就能看出来,LinkedList只需要断开链接即可,而ArrayList需要进行大量元素的移动后插入。
(这道题也就是间接问你关于hashmap的数据结构了)
这得从它的底层数据结构说起,HashMap的是由数组+链表的结构实现的(当时忘了阈值超过8,演化为红黑树这一点了,面试完才想起来没说),它的内部封装了一个Entry数组,该数组也是一个哈希数组,故而存在哈希冲突的问题,HashMap是通过链地址法来解决冲突问题的,在每一个数组节点下封装一个单链表,所以put()方法添加一个新元素时先通过计算该元素的hash值,再通过hash&(length-1)确定该元素在Entry数组中的下标位置,若无元素则添加,若存在元素再通过equals方法来判断该元素是否在该链表中,如果不存在则放在头结点位置,如存在则不添加。
hashmap中有两个构造参数,一个初始容量(默认16),另一个为加载因子(默认0.75),当当前存储大于初始容量与加载因子的乘积值时,则进行扩容操作,每次已二倍的速率增长,最大值为2*30(幂次)。
扩容是新建了一个数组,会重新计算hash来获取元素的新位置,所以扩容是一个相当耗时的操作。
平时用MySQL比较多一些。
(这一块不是很熟,答的不好)
(竟然紧张到忘记说ACID了,直接说了事务隔离级别。。。蠢了)
ACID大家应该都清楚吧,原子性、一致性、隔离性、永久性。
隔离级别包括四个级别:
脏读:发生在一个事务A读取了被另一个事务B修改,但是还未提交的数据。假如B回退,则事务A读取的是无效的数据。
幻读 :幻读发生在当两个完全相同的查询执行时,第二次查询所返回的结果集跟第一个查询不相同。
索引的数据结构包含B+树和哈希表两种。一般用B+树比较多(接下来就是无限的B+树怒怼环节了,晕)
读者可以自行百度查看。推荐阅读(https://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html)
B+树是B树的一种变形。
B树定义:
M表示阶数。
B树特点:
一棵m阶的B+树和m阶的B-树的差异在于:
(这一部分不太懂,当时疯狂说深度低,二叉顺序访问之类的。。。面试官引导磁盘访问效率和内存访问效率时间量级问题,我也很晕菜啊。。。下来百度学习了一下)
一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。
磁盘存取原理:
索引一般以文件形式存储在磁盘上,索引检索需要磁盘I/O操作。与主存不同,磁盘I/O存在机械运动耗费,因此磁盘I/O的时间消耗是巨大的,一般是毫秒级别,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存
B+树的优点:
(当时只记起来五层模型。。。)
七层模型:
物理层—数据链路层—网络层—传输层—会话层—表示层—应用层
五层模型:
物理层—数据链路层—网络层—传输层—应用层
三次握手:
四次挥手:(可以理解为三次挥手+半关闭)
终止连接一般是由客户端发起的。
(当时把TIME-WAIT和停止等待协议弄混了。。。说了半天ARQ)
TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证。
可以理解为主动关闭连接的一方,要停留在TIME-WAIT状态,等待2*MSL(4分钟,Centos7上默认配置的值是1分钟)时间才可以再次回到CLOSED状态,在等待期间该端口(socket)不能被回收使用,即不能正常连接请求。具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务。
IOC:控制反转,是一种设计思想,就是 将原本在程序中手动创建对象的控制权,交由Spring框架来管理。IOC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。
AOP:面向切面编程,能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
AOP是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用Cglib ,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理。
CGlib是一个字节码增强库,为AOP等提供了底层支持。
通过实现MethodInterceptor接口,重写其中的Intercept方法(拦截器)
(1)客户端(浏览器)发送请求,直接请求到 DispatcherServlet。
(2)DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。
(3)解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由 HandlerAdapter 适配器处理。
(4)HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑。
(5)处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。
(6)ViewResolver 会根据逻辑 View 查找实际的 View。
(7)DispaterServlet 把返回的 Model 传给 View(视图渲染)。
(8)把 View 返回给请求者(浏览器)
一些基本的输入输出流介绍。
它是同步非阻塞的,还有异步非阻塞的AIO;
(没有啊。。。)
面试官:好了,面试就到这吧,有什么想问的吗?
我:emmm,面试的不是很好,准备不充分。。。
面试官:比大部分人好多了(我心里有b数的。。)
我:嗯嗯,谢谢面试官。
面试官:好的,那就这样了,拜拜!
我:恩,拜拜!
希望下次可以面试的更好一点,加油吧!