开场白
面试官很友好,先是自我介绍,面试官应该是做永劫无间手游的,刚好内测的时候玩了几局,简单聊了一下,然后开始正式面试了。
第一个问题,3次握手和4次挥手
- 回答:
- 三次握手:TCP 建立连接的过程,包括 SYN(同步)、SYN-ACK(同步-确认)、ACK (确认)三个步骤。
- 四次挥手:TCP 断开连接的过程,包括 FIN(结束)、ACK(接受)、FIN(结束)、ACK(接受) 四个步骤。
第二个问题,讲讲udp和tcp区别
- 回答:
- TCP:面向连接,提供可靠的数据传输,保证数据顺序和完整性,但速度较慢。
- UDP:无连接,提供不可靠的数据传输,不保证数据顺序和完整性,但速度较快。
第三关问题,延伸问题;你刚刚提到TCP和UDP头部大小不同,它们分别是什么
- TCP:头部较大(20字节),包含序列号、确认号、窗口大小等信息。
- UDP:头部较小(8字节),仅包含源端口、目的端口、长度和校验和。
第四个问题,讲讲JVM
JVM就是Java虚拟机
JVM就像是一个神奇的翻译官,它可以把Java代码转换成计算机能理解的语言。具体来说:
1. 当我们编写Java代码时,它会被编译成一种叫做字节码(Bytecode)的中间形式
- JVM会读取这些字节码,并在不同的操作系统上执行它们
- 这样,Java程序就可以"一次编写,到处运行"啦!
JVM的主要工作包括:
- 加载类文件
- 验证字节码
- 执行代码
- 管理内存
- 提供运行时环境
第五个问题是延伸问的Java的类加载机制
这里博主之前有做相关博客内容可以看看,Java类加载机制-CSDN博客
这里是简单的回答
Java的类加载机制主要分为以下几个步骤:
1. 加载(Loading)
- 通过类的全限定名获取类的二进制字节流
- 将字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成一个代表该类的Class对象
2. 验证(Verification)
- 确保Class文件的字节流符合JVM规范
- 检查文件格式、元数据、字节码、符号引用等
3.准备(Preparation)
- 为类变量分配内存并设置默认值
- 注意:这里只是设置默认值,不是初始化值哦
4.解析(Resolution)
- 将常量池中的符号引用替换为直接引用
5.初始化(Initialization)
- 执行类构造器<clinit>()方法
- 真正开始执行类中定义的Java程序代码
双亲委派模型的工作流程是:
- 当一个类加载器收到类加载请求时,首先不会自己尝试加载
2. 而是把这个请求委派给父类加载器去完成
3. 只有当父类加载器无法完成加载时,子加载器才会尝试自己加载
这样的机制可以避免类的重复加载,也保证了Java核心类库的安全性呢!
第六个问题,讲讲java中的缓存是什么
1. 什么是缓存?
- 缓存是存储在内存中的临时数据
- 它可以减少重复计算或数据库查询的次数
- 让程序运行得更快更高效
2. Java中常见的缓存类型:
- 内存缓存:使用Map或ConcurrentHashMap实现
- 分布式缓存:如Redis、Memcached
- 浏览器缓存:用于Web应用
- CPU缓存:硬件级别的缓存
3. 缓存的优点:
- 提高系统性能
- 减少数据库压力
- 提升用户体验
4. 缓存的缺点:
- 数据可能不是最新的
- 占用内存资源
- 需要处理缓存一致性问题
Java中有很多优秀的缓存框架,比如:
- Guava Cache:Google提供的轻量级缓存
- Ehcache:功能强大的Java缓存
- Caffeine:高性能的Java 8缓存库
使用缓存时,我们还需要考虑缓存策略,比如:
1. 缓存淘汰策略:
- LRU(最近最少使用)
- FIFO(先进先出)
- LFU(最不经常使用)
2. 缓存更新策略:
- 定时刷新
- 写时更新
- 失效时更新
第七个问题,ConcurrentHashMap和HashMap以及Hashtable的区别
1. HashMap:
- 非线程安全
- 允许null键和null值
- 性能最好
- 不保证元素的顺序
- 使用数组+链表+红黑树实现
2. Hashtable:
- 线程安全(通过synchronized实现)
- 不允许null键和null值
- 性能较差
- 是Java早期的集合类
- 使用数组+链表实现
3. ConcurrentHashMap:
- 线程安全(通过分段锁实现)
- 不允许null键和null值
- 性能接近HashMap
- 支持高并发
- 使用数组+链表+红黑树实现
1. 单线程环境:使用HashMap
2. 多线程环境:使用ConcurrentHashMap
3. 遗留系统:可能会遇到Hashtable
算法题
第一题是LCR 085. 括号生成
第二题,二分查找
题目1:查找目标值的第一个出现位置
要求:
给定一个升序数组 nums 和目标值 target,返回 target 第一次出现的索引,若不存在返回 -1。
示例:
输入:nums = [1,2,2,2,3], target = 2 → 输出:1
输入:nums = [5,7,7,8,8,10], target = 6 → 输出:-1
public int firstOccurrence(int nums[],int target){
int result = -1;
int left = 0;
int right = nums.length-1;
while (left<=right){
int mid =left + (right - left)/2;
if(nums[mid]==target){
result = mid;
right = mid - 1;//找更前边的target
} else if (nums[mid]<target) {
left = mid + 1;
}else {
right = mid - 1;
}
}
return result;
}
脑图
看不清可以看附件