- TCP三次握手后,连接建立后,操作系统会为进程分配哪些资源?
- 套接字
- 文件标识符
- 内存
- 端口和带宽
- 输入输出的缓冲区
- 定时器,用于超时重传
- 连接状态信息的保存
- OSI网络七层模型?
- 应用层
- 为用户提供服务
- 表示层
- 数据处理和数据编码、解码操作
- 会话层
- 管理应用程序之间的会话
- 传输层
- 为网络中两台机器中的进程提供数据传输服务
- 网络层
- 路由和寻址
- 数据链路层
- 帧编码和误差纠正
- 物理层
- 透明的传输比特流
- 应用层
- 数据库设计的规范(范式)?
- 一范式:属性不可再分割,即字段只能是一个值,不能继续分割
- 二范式:二范式在一范式的基础上消除了非主属性对码的依赖,而添加了一个字段,即主键,所有非主属性都依赖于主键
- 三范式:消除了非主属性对码的传递依赖
- 数据库索引底层结构(b+树),为什么采用该结构?
- 底层采用B+树,其是B树的变种,B树是一种矮胖的树形结构,而查询的效率瓶颈在于树的高度,B树能够最大可能降低树的高度,每个节点存放多个索引,每个索引左右都有一个指针,左指针指向比当前索引小的子树,右指针指向比当前索引大的子树。B树能够在大数据量的情况下保证树的高度为个位数,减少检索次数,进而减少IO次数。而B+树与B树的不同点在于,B+树的非叶子节点并不存放实际的行数据,而叶子节点存放实际数据,并且前后相连成为一个双向链表,便于范围查询的同时,还可以增加一个数据页中的索引数量,进一步减少IO次数。
- 为什么采取该结构,前面已经说了B+树相较于B树的优点,这里说一下B树相较于其他一些快速检索的数据结构的优点,以Hash表为例,哈希表在数据量较小的时候检索非常快,但是大数据量会带来大量的哈希冲突,并且作为哈希表的数组的容量也有瓶颈。而其他类似平衡二叉树,红黑树和快表这种结构,在大数据量的时候树或者索引的层数都很高,查询效率很一般,甚至有着性能瓶颈,并且他们在插入删除时为保持数据结构做的调整带来的性能消耗也比B树要大的多
- 数据库隔离级别,如何实现?
- 读未提交:不加锁
- 读已提交:写操作通过在操作数据时上互斥锁,在修改完数据后释放锁,读操作通过MVCC实现,每次读取数据都会生成一个readView
- 可重复读:写操作在写数据时上互斥锁,在事务提交或者回滚时会释放锁,读操作依赖MVCC,在第一次读取数据时会生成一个readView,之后沿用。
- 串行化:读操作和写操作都通过上互斥锁来实现,直到事务结束才会释放,性能很差。
- JVM内存模型,堆空间划分哪些区,年轻代划分,分配一个对象的流程,年轻代空间会占满吗?
- JVM内存模型:
- 堆区:
- 对象存放
- 字符串常量池
- 线程私有区域
- 程序计数器
- 虚拟机栈
- 局部变量表:存放局部变量和数据类型
- 操作数栈:存放方法执行过程中的中间值
- 动态链接:用于将符号引用转化为直接引用
- 方法返回地址
- 本地方法栈:类似于虚拟机栈,不过是用于本地方法
- 元空间:
- 类信息,静态变量,常量,即时编译之后的代码
- 运行时常量池:
- 符号引用:
- 类符号引用
- 字段符号引用
- 方法符号引用
- 接口方法符号引用
- 字面量
- 整数
- 浮点数
- 字符串字面量
- 符号引用:
- 直接内存:一般用于IO
- 堆区:
- 堆空间划分区域:
- 字符串常量池
- 存放对象的区域:
- 年轻代
- Eden区
- Survivor区
- 老年代
- 年轻代
- 分配一个对象的流程:
- 类加载过程:
- 加载:将字节码加载入内存
- 验证:验证该类是否符合JVM的规范
- 准备:为类变量分配默认值
- 解析:将符号引用转变为直接引用
- 分配内存:为这个对象分配内存
- 设置默认值:为对象的变量设置默认值
- 调用构造器实例化对象
- 返回对象对应的引用
- 对象使用
- 垃圾回收
- 类加载过程:
- 年轻代空间会占满吗?
- 有这种可能,但是很快会触发young gc,将要一些要GC的对象回收,并将剩余的对象复制到老年代
- 出现的场景:
- 对象创建速度过快
- survivor区域过小
- 对象存活率过高
- JVM内存模型:
- 类加载机制,双亲委派模型如何保证核心类库的安全性,举具体的例子?
- 类加载机制:
- 加载:将字节码文件的字节流输出内存
- 验证:字节码是否符合JVM的规范
- 准备:为类变量设置默认值
- 解析:将符号引用转为直接引用
- 初始化
- 双亲委派模型:
- 当要加载一个类时,从底向上依次问父类加载器该类是否已加载,如果已加载直接返回即可
- 如果一直到最上层BootstrapClassLoader都没有加载这个类,那么从上往下依次看当前类加载器是否能加载这个类,如果能加载,则加载返回,如果不能加载,则向下看子类加载器是否能加载。
- 如果要打破双亲委派模型,只需要重写loadClass()方法即可
- 保证核心类库安全性的例子?
- 例如String类,如果我们自己定义了一个类也叫java.lang.String,想恶意修改核心类库,但是类加载的时候,核心类库中的String类已经在BootstrapClassLoader中被加载,而自定义的String类需要ApplicationClassLoader去加载,然而此时已有String类被加载,那么自定义的String类永远不会被加载。
- 类加载机制:
- springmvc涉及的组件、执行的流程(dispatcherservlet等)?
- dispatcherServlet
- HandlerMapping
- HandlerAdapter
- Handler
- 执行过程:
- 客户端的请求到达DispatcherServlet,DispatcherServlet将请求的url转发到HandlerMapping,找到对应的执行链,返回给DispatcherServlet,DispatcherServlet会执行执行链中的所有拦截器的preHandle方法,然后转发给HandlerAdapter,会去解析参数,并将请求发送给对应的Handler去执行,返回值会返回给HandlerAdapter,HandlerAdapter会处理返回值,默认将返回值转换为JSON格式,然后将返回值和执行链返回给DispatcherServlet,然后DispatcherServlet拿到返回值和执行链后执行所有拦截器的postHandle方法,执行完毕后将返回值返回给客户端,客户端关闭请求后,DispatcherServlet执行拦截器的afterCompletion方法
20240806面经背诵
最新推荐文章于 2024-10-12 10:41:56 发布