北大面试集合部分
Posted boy快快长大
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了北大面试集合部分相关的知识,希望对你有一定的参考价值。
北大面试集合部分
1.前言
是敖丙出的一个面试的视频,面试的人是北大的硕士有两年的工作经验。
程序员面试北大研究生Java岗,中途离场,是不是玩不起?
2. 集合部分
Q1:集合你平时用的多的有哪些
集合的话像Collection下的ArrayList、LinkedList,像Set集合中的HashSet,另外再Map中比较常用的是HashMap设计到线程安全的话可能会用到ConcurrentHashMap
Q2:我们先聊一下ArrayList和LinkedList吧还有它们两个使用的场景
首先ArrayList它底层是数组,它初始化的时候它的数据量是零,当你add的时候它会默认变成10,它的扩容每次扩容是它之前容量的1.5倍,它的特性是查找比较快,它的删除效率比较低。LinkedList的底层是带有头结点和尾结点的双向链表,它提供两种插入方式一个是头插LinkedFirst还有一个尾插LinkedLast,它的特性非常适合经常增加、删除操作的场景。它的查询在量大的时候会比较慢。它在查询的时候是链表查询,查询的时候会拿值按照顺序从第一个开始一个一个的进行比较;而ArrayList查询是根据脚标查询的,所以会很快。
Q3:如果遇到线程安全的一些情况下,但是你又想使用List的情况怎么办?
这个有一个解决的办法就是使用一个老土的Vector,它跟ArrayList一样底层都是一个数组,它与ArrayList有一点区别是它其中大部分方法都被Synchronized关键字所修饰,所以说他是一个线程安全的。它扩容的时候与ArrayLst还有点区别,它的扩容大小是2倍进行扩容的。
Q4:刚才你还提到了Map包下面的像HashMap,我们就聊一下HashMap
Map集合下常用的有HashMap首先HashMap主要用来放键值对,它是基于哈希表的Map接口实现的,是非线程安全的,HashMap可以存储值为null的key和value,但null作为key只能有一个而作为value却可以有很多个,在jdk1.7的时候它的底层是一个数组加上一个单链表,数组是HashMap的主体,链表是为了解决哈希冲突而存在的(“拉链法解决”),到了1.8的时候就变成了数组加上单链表或者说是红黑树的方式,单链表和红黑树之间相互转换。他的单链表长度≥8,并且他的数组长度≥64的时候,它的单链表会转化成红黑树的形式。
它在红黑树的节点数量,如果要是小于6的时候,它会重新再转化成一个单链表这是他底层的一个变化,另外一点就是关于它的数组的数量,默认是16,他的阈值是0.75,这还关乎到它的扩容。
扩容的时候HashMap会检查数组里元素的个数,因为有loadFactor的默认值是0.75,它的数组长度默认是16,阈值为0.75,16*0.75=12,当他的数组长度大于12的时候,他就会触发扩容,扩容成之前哈希桶长度的而被(哈希表总以2的幂作为哈希表的大小),然后把之前元素重新进行一次哈希计算,然后添加到新的数组里面。
Q5:你跟我说一下它是不是线程安全的
它不是线程安全的,因为他在插入的时候多线程会有数据覆盖的可能。另外再1.7的时候,在put的时候会有一个resize的过程,这个过程会造成它的头插,会形成一个环形链表导致一直死循环。在1.8的时候改成尾差了
Q6:如果要用线程安全的Map呢
直接使用ConcurrentHashMap替代来保证它的线程安全
Q6:还有个HashTable或者Collection.Synchronized来代替
Q7:你跟我聊一下ConcurrentHashMap
首先它的数据结构在1.7版本底层是个分片数组,它为了保证线程安全它他有个Segment锁,这个Segment继承于ReentrantLock来保证它的线程安全的,它每次只给一段加锁来保证它的并发度。另外在1.8的时候它改成了和HashMap一样的数据结构。数组加单链表或者红黑树的数据结构,在1.8版他会逐渐放弃这种分片锁机制,而使用Synchronized和CAS来操作,因为在1.6版的时候JVM对Synchronized的优化非常大,它现在也是用这种方法来保证它的线程安全。
Q8:刚才你提到了1.7版之前Segment分段锁,那你知道它如果要找到具体的值,他会经过几次哈希吗?或者它是如何去找到一个具体数值的?
这个候选人没有看过!
Q9:刚说1.8版之后它是CAS加Synchronized,那CAS(Compare And Swap)是什么?
CAS相当于一个轻量级的加锁的过程,比如说你要修改一个但在并发量不是特别大的情况下,锁竞争不激烈你要修改东西,你要先查,查完之后再修改,修改完准备写之前,它会再查一次,比较之前的结果有没有区别,如果有区别的话说明这个修改是不安全的,如果没有修改说明是安全的,这时它可以安全的去修改。而不是直接加锁的那种形式。在低并发的情况性能可能会好一点的。
比较并替换(Compare And Swap)
Q10:它有什么优缺点,刚才你说优点是轻量级,那在高并发情况下大量使用它,它有什么缺点呢?
首先当并发量特别大的时候,它始终有个忙循环的过程对CPU的性能消耗还是比较大的,当高并发的时候直接使用状态机,锁之类的,另外一个他可能会产生一个ABA的问题,之前读和过段时间读中间会被第三人修改过, 但是它又给改回来了。这个问题可以通过添加一个戳或者标志位来解决。
Q11:刚才你提到了Synchronized,在跟我聊下它
关于Synchronized。可以比如说同步代码块,还有它同步代码块时可以指定任意的锁,对象作为锁,当它应用于方法上,它的锁就是this,如果要是静态方法则锁定是它的class对象,关于Synchronized在JDK1.6时候升级还是蛮大的。
// TODO 11:37
Java开发基础面试题,北大青鸟java培训多久
Java NIO 基本介绍
- Java NIO 全称 java non-blocking IO,是指 JDK 提供的新 API。从 JDK1.4 开始,Java 提供了一系列改进的输入/输出的新特性,被统称为 NIO(即 New IO),是同步非阻塞的
- NIO 相关类都被放在 java.nio 包及子包下,并且对原 java.io 包中的很多类进行改写。
- NIO 有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器)
- NIO是 面向缓冲区 ,或者面向 块 编程的。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性,使用它可以提供非阻塞式的高伸缩性网络
- Java NIO的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。
- 通俗理解:NIO是可以做到用一个线程来处理多个操作的。假设有10000个请求过来,根据实际情况,可以分配50或者100个线程来处理。不像之前的阻塞IO那样,非得分配10000个。
- HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。
NIO 和 BIO 的比较
- BIO 以流的方式处理数据,而 NIO 以块的方式处理数据,块 I/O 的效率比流 I/O 高很多
- BIO 是阻塞的,NIO 则是非阻塞的
- BIO基于字节流和字符流进行操作,而 NIO 基于 Channel(通道)和 Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择器)用于监听多个通道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道
NIO 三大核心原理示意图
一张图描述NIO 的 Selector 、 Channel 和 Buffer 的关系
- 每个channel 都会对应一个Buffer
- Selector 对应一个线程, 一个线程对应多个channel(连接)
- 该图反应了有三个channel 注册到 该selector //程序
- 程序切换到哪个channel 是有事件决定的, Event 就是一个重要的概念(EventLoop)
- Selector 会根据不同的事件,在各个通道上切换
- Buffer 就是一个内存块 , 底层是有一个数组
- 数据的读取写入是通过Buffer, 这个和BIO , BIO 中要么是输入流,或者是输出流, 不能双向,但是NIO的Buffer 是可以读也可以写, 需要 flip 方法切换
- channel 是双向的, 可以返回底层操作系统的情况, 比如Linux , 底层的操作系统通道就是双向的.
下面我们就开始一一来学习NIO的三大组件吧
缓冲区(Buffer)
基本介绍
缓冲区(Buffer):缓冲区本质上是一个可以读写数据的内存块,可以理解成是一个容器对象(含数组),该对象提供了一组方法,可以更轻松地使用内存块,,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况。Channel 提供从文件、网络读取数据的渠道,但是读取或写入的数据都必须经由 Buffer,如图: 【后面举例说明】
Buffer 类及其子类
- 在 NIO 中,Buffer 是一个顶层父类,它是一个抽象类, 类的层级关系图:
- Buffer类定义了所有的缓冲区都具有的四个属性来提供关于其所包含的数据元素的信息:
最后总结我的面试经验
2021年的金三银四一眨眼就到了,对于很多人来说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。
另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。
资料领取方式:点击这里免费获取
BAT面试经验
实战系列:Spring全家桶+Redis等
其他相关的电子书:源码+调优
面试真题:
(img-J3yJweeQ-1625649576097)]
[外链图片转存中…(img-ad2rl5qe-1625649576098)]
以上是关于北大面试集合部分的主要内容,如果未能解决你的问题,请参考以下文章