后端开发刷题 | 面试篇3
说一说HashMap的扩容机制
1. 初始容量和加载因子
- 初始容量(Initial Capacity):
HashMap
在创建时可以指定一个初始容量,它是桶数组(Entry<K,V>[] table
)的初始大小。如果没有指定初始容量,则默认为 16。- 加载因子(Load Factor):加载因子是
HashMap
在其容量自动增加之前可以达到多满的一个尺度。当HashMap
中的条目数超过了加载因子与当前容量的乘积时,就会进行扩容。如果没有特别指定,加载因子默认为 0.75。2. 扩容过程
当
HashMap
中的元素个数超过容量 * 加载因子
时,就会触发扩容。扩容的过程大致如下:
创建一个新的桶数组:新数组的容量是旧数组容量的两倍(如果旧数组容量是
MAXIMUM_CAPACITY
(即1 << 30
),则不再扩容,因为已经到达最大容量)。重新计算索引:遍历旧数组中的每个元素,根据每个元素的键重新计算哈希值,并据此确定元素在新数组中的索引位置。这里可能会遇到哈希冲突,但
HashMap
通过链表或红黑树(Java 8 引入)来解决冲突。复制元素:将旧数组中的元素复制到新数组中对应的位置。如果是链表,则直接整体移动;如果是红黑树,则进行红黑树的复制。
替换桶数组:将
HashMap
的table
引用指向新的桶数组。
IP协议的首部结构
首部协议一共是20个字节(固定)
第一个4字节: 版本号;首部长度; 服务类型;总长度;
第二个4字节:标识;标志;片偏移;
第三个4字节:生存时间;协议;校验和;
第四个4字节:源ip地址;
第五个4字节:目的ip地址;
说一说进程调度算法有哪些
1. 先来先服务(FCFS,First-Come, First-Served)
- 描述:按照作业或进程到达任务队列的顺序进行调度。它是一种非抢占式的调度算法,即一旦CPU分配给某个进程,该进程将一直执行,直到完成或发生某种阻塞事件。
- 优点:易于理解且实现简单,只需要一个队列,并且相当公平。
- 缺点:对短作业(进程)不利,可能导致其长时间等待,同时也不利于处理紧急作业。
2. 时间片轮转(RR,Round-Robin)
- 描述:将CPU处理时间划分为多个时间片,每个进程被分配一个时间片,进程在时间片结束时被抢占,并重新放入队列末尾等待下一次调度。
- 优点:简单易行,平均响应时间短,可以保证每个进程都有机会获得CPU资源,防止长时间运行的进程垄断CPU。
- 缺点:时间片大小需要设置得合适才能实现最好的性能,过大可能导致响应时间过长,过小则会导致频繁的进程切换,增加系统开销。
3. 最短作业优先(SJF,Shortest Job First)
- 描述:每次从队列中选择预计执行时间最短的作业或进程进行调度。该算法可以是抢占式的,也可以是非抢占式的。
- 优点:可以降低平均等待时间和提高系统吞吐量,优先照顾短作业。
- 缺点:对长作业不友好,可能导致其长时间得不到执行,出现饥饿现象。同时,难以准确估计作业的执行时间,影响调度性能。
4. 最短剩余时间优先(SRTF,Shortest Remaining Time First)
- 描述:是SJF算法的抢占式版本。每次调度时,选择剩余执行时间最短的进程执行。如果新到达的进程剩余执行时间更短,则抢占当前执行的进程。
- 优点:确保短作业或短进程优先被处理。
- 缺点:由于频繁的抢占和进程切换,系统开销大,实现代价高。
5. 最高响应比优先(HRRN,Highest Response Ratio Next)
- 描述:根据响应比R=(等待时间+服务时间)/服务时间进行调度。响应比越高,进程优先级越高。
- 优点:既考虑了作业的等待时间,又考虑了作业的执行时间,使得长作业也有机会得到执行。
- 缺点:需要一直计算响应比,增加了系统资源的消耗。
6. 多级反馈队列调度算法(Multilevel Feedback Queue Scheduling)
- 描述:设置多个就绪队列,并为每个队列赋予不同的优先级和时间片大小。进程首先进入最高优先级的队列,如果在时间片内未完成,则降入下一级队列,以此类推。仅当高优先级队列为空时,才调度低优先级队列中的进程。
- 优点:公平性好,能够适应多种不同的任务,不必事先知道进程的执行时间。
- 缺点:设计复杂,实现难度较大。
介绍一下Java中的IO流
一、IO流的基本概念
- 流:是一种抽象的概念,代表数据的无结构化传递。流是一个无结构化的数据组成的序列,以字节或字符形式输入或输出。
- 输入流:数据从外部数据源流入到程序内部的过程。
- 输出流:数据从程序内部向外部流出到数据目的地的过程。
二、IO流的分类
1. 按处理的数据类型分类
- 字节流:以字节(Byte,1Byte=8bit)为单位进行读写操作,可以处理所有类型的数据,如图片、视频等二进制文件。主要类有
InputStream
和OutputStream
。- 字符流:以字符(通常是16位Unicode字符)为单位进行读写操作,更适合处理文本数据。主要类有
Reader
和Writer
。2. 按数据的流向分类
- 输入流:用于从外部数据源读取数据到程序中,如
FileInputStream
、BufferedReader
等。- 输出流:用于将程序中的数据输出到外部目的地,如
FileOutputStream
、BufferedWriter
等。3. 按处理数据功能分类
- 节点流(又称实体流):直接对数据源或目的地进行读写操作,如
FileInputStream
、FileOutputStream
等。- 处理流(又称装饰流):不直接连接数据源或目的地,而是对已有的流进行封装,提供额外的功能,如缓冲、转换等。常见的处理流有
BufferedInputStream
、BufferedOutputStream
、BufferedReader
、BufferedWriter
等。三、IO流的主要类和方法
Java的IO流体系涉及多个类和接口,但核心类主要包括
InputStream
、OutputStream
、Reader
和Writer
四个抽象类及其子类。这些类提供了丰富的方法来支持数据的读写操作,如read()
、write()
、close()
等。