面试题汇总

TCP/IP

《计算机网络原理:自顶向下方法》《TCP/IP详解卷1》《图解TCP/IP》《图解HTTP》

  1. TCP和UDP的区别和优缺点?
    参考
  2. 三次握手四次挥手的过程
    • 三次握手:
      • 客户端和服务器都建立TCB
      • 客户端向服务端发送TCP报文,其中SYN指针设置为1,消耗一个序列号,进入同步发送状态;不能携带数据。
      • 服务端向客户端发送TCP报文,其中SYN指针设置为1,ACK指针设置为1,消耗自己序列号1个,确认序列号为客户序列号加1,进入同步接收状态;不能携带数据。
      • 客户端发送,ACK指针设置为1,确认序列号为服务端序列号,此时可以携带数据,如果不发送数据就不消耗序列号。进入已建立状态。
      • 服务端收到确认报文后也进入建立状态。
    • 四次挥手
      • 客户端发送FIN指针为1,序列号为x;进入终止等待1状态;
      • 服务端发送ACK指针为1,序列号为y,确认序列号为x+1;服务端进入关闭等待状态;客户端收到时进入终止等待2状态;
      • 服务端发送FIN指针为1,FIN=1,ACK=1,seq=z,ack=x+1;服务端进入关闭等待状态;
      • 客户端接收后发送一个ACK=1,ack,seq的报文,进入时间等待状态;等待两倍最大报文段寿命后关闭。
      • 服务端接收到后直接关闭。
  3. 能不能两次握手
    不能。假如客户端发送了一次握手后由于网络延迟原因晚到达,在这期间要是客户端再次发送确认,在服务器收到第二次同步请求时就建立了连接,此时如果第一次同步请求由于网络通畅到达了,那么就会造成两次建立连接,导致不必要的错误或资源浪费。
  4. 能不能三次挥手
    不能。需要服务端传输数据的时间。
  5. 如果建立连接后客户端故障咋办。
    有计数保活器,每次接收到客户端资源都会更新保活器,如果两个小时没接收到,那就发送探测报文端,没75秒发送一个,一连10个都没反应就关闭连接。
  6. 如何保证可靠性
    • 超时重传:有一个定时器,超时没收到确认码就重新传输。
    • 数据报检验:端对端的检验,防止到达目的IP后,在分用的时候可能会出现问题。
    • 流量控制:通过滑动窗口控制流量
    • 拥塞控制:慢开始(一开始就发送大量数据容易拥塞)、拥塞避免 (拥塞窗口缓慢变大)、快速重传和恢复(一个没确认,但后续三个确认了,就迅速重传没确认那个)
    • 数据包重排序:
    • 停止等待协议:发完一个分组就停止发送,等待对方发送确认码。
      2-5参考
  7. TCP/IP有几层?每一层的作用?MAC地址在哪层?
    • 四层:应用层,传输层,网络层,链路层
    • 链路层:物理接口方面的,以太网协议,点对点协议
  8. 有什么应用层协议
    HTTP、DNS、DHCP、SMTP
  9. IPv4、IPv6
    • 长度不同,一个32位一个128位
    • 安全性不同,ipv6可以加密传输
    • 路由表大小不同,IPv6的路由表相比IPv4的更小
    • IPv6的组播支持以及对流的支持要强于IPv4
    • IPv6使用NDP,IPv4使用ARP
  10. ARP协议
    地址解析协议,先查ARP缓存,然后先匹配网络号和子网号,再匹配默认,广播方式发送局域网。
  11. http状态码
    200是请求请求成功,300重定向,400客户端错误,500是服务端错误。
  12. request和response
    request发送请求头,包括方法、URI和协议版本,请求字段,请求主体;response中有响应头,包括协议版本,状态码,状态信息,返回头和主体。

算法

  1. 数组与链表的区别

    • 数组连续存储,链表不连续
    • 数组通过下标访问,链表通过结点存放的地址访问
    • 数组定长,链表不定长
  2. 二分查找过程
    取中位数进行比较,然后对

  3. 二叉树遍历方式,后序过程
    前序、中序、后序遍历。

  4. 快排过程

  5. 二叉树先序遍历和后序遍历结果相同是什么二叉树
    只有一个父节点的树

  6. 双向链表节点删除

  7. 单链表给两个指针怎么检验是否有环。快慢指针的方式,

  8. 堆排序为啥不稳定和建堆时间
    自上而下建堆是O(nlogn),自下而上是O(n)

  9. 循环队列三种方式

    • 设定一个flag,初始化为false,在存的时候为true,取的时候为false
    • 设定一个count值
    • 空出一个值

Java

  1. 面向对象的设计要素
    • 封装性
    • 多态性
    • 继承性
  2. 设计原则
    • 单一职责原则(Single Responsibility Principle):一个类只负责一项职责
    • 接口隔离原则(Interface Segregation Principle):一个类对另一个类的依赖应该建立在最小接口上
    • 依赖倒转原则(Dependence Inversion Principle):高层模块不要依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象;面向接口编程
    • 里氏替换原则(Liskov Substitution Principle):在子类中尽量不要重写父类方法
    • 开闭原则(Open Closed Principle):对扩展开放,对修改关闭
    • 迪米特法则:对象与对象之间应该保持最少的了解;只和直接朋友(成员变量、返回类型、参数类型)通信,即类方法中不要以陌生对象作为局部变量。
    • 合成复用原则(Composite Reuse Principle):尽量使用合成或聚合而不是继承。
  3. Java的基本变量有哪些?类型占用字节?
    字符型:char。字节大小:2
    布尔型:boolean。Java虚拟机规定为4个字节。
    整数型:byte、short、int、long。字节大小:1 2 4 8
    浮点型:float、double。字节大小:4 8
    空类型:void
    内部使用:returnAddress
  4. 构造函数能被重写吗?能被重载吗?子类的super是重写吗?
    能被重载,不能被重写。子类的super不是重写,是调用,必须在构造函数的第一行。
  5. List和Set区别是什么?Set为什么能去重?
    • List能存放重复对象,Set不可以
    • List有序,Set无序
  6. HashMap底层原理:bucket扩容?k冲突了怎么办?
    扩容是通过复制来的,扩容后的大小为2的幂次方,这跟二次hash计算有关系,然后就是进行拷贝。hash冲突了就先检查bin的第一个node中key值是否相等,如果相等就直接返回,否则就检查第一个node的类型,如果是不是TreeNode,那么就按照链表方式查到链尾,然后添加元素,但是这个时候要判断链长是否超过阈值,默认是8,如果超过了,就将该链转为红黑树;如果检查为TreeNode类型,则直接TreeNode添加结点方法。
  7. Volatile用过吗?有什么作用?
    使对象具备可见性,即当对volatile对象进行写操作时,会更新到主存中,其他线程的读需要到主内存中进行读取,内在原理是内存屏障,因此也能防止指令重排。
  8. Java内存机制
    每个线程有私有栈,方法区存放类(包含静态变量),堆存放对象。
  9. 接口和抽象类的区别有哪些?里面变量有什么不同吗?方法有什么不同?
    • 类继承一个抽象类,却可以实现多个接口
    • 抽象类方法有默认实现,接口不存在默认实现
    • 抽象类访问修饰符都可以用,接口只能是public
    • 都不可以被实例化
  10. 线程的创建方式有哪几种?创建方法说下?
    • 继承Thread,重写run方法
    • 实现Callable,重写call方法
    • 实现Runable,重写run方法
  11. String abc = new Stirng("111"),新建了几个对象?abc指向哪?
    创建了两个对象,一个在常量池中,一个从常量池拷贝到堆中,abc指向堆中String对象。
  12. 对象和类的差异
  13. 常用设计模式
    • 创建者模式
      • 简单工厂模式,工厂方法模式
      • 单例模式
    • 结构型模式
      • 原型:实现clone
      • 适配器:类适配器,方法适配器
      • 代理模式:静态代理,动态代理
    • 行为者模式
      • 策略者(多态)
      • 观察者:注册观察者
      • 责任链模式:ClassLoader?
  14. 多态了解
  15. JVM类加载机制
    • (1)加载:查找并装载类型的二进制数据
    • (2)连接 :验证(四次class验证),准备(类变量分配内存并初始化),解析(符号引用转为直接引用)
    • (3)初始化:把类变量初始化为正确的初始值
  16. GC
    分代:young、old
  17. 字节码

操作系统

《深入理解计算机系统》 《Linux内核设计与实现》《深入理解linux内核》《Linux高性能服务器编程》

  1. 进程间通讯用什么
    管道、FIFO、消息队列、信号量、共享内存
  2. 进程阻塞是怎么做到的
    等锁、IO
  3. 多线程是什么
  4. 有哪些锁分别解释一下
    • 乐观锁:认为数据不会被修改,所以不会加锁,只会在更新数据时做检查,通常使用CAS算法
    • 悲观锁:认为数据会被修改,加锁。
  5. 缓存的作用以及缓存替换算法
  6. 虚拟文件系统
  7. 进程和线程之间的区别
    • 进程:线程是CPU调度的最小单元,切换需要把当前进程寄存器中数据存储到PCB中,然后把切换目标进程PCB中的数据赋值到寄存器中。
    • 线程:是进程调度的最小计算单元,共享内存。切换时把当前线程的指令地址指针存放到TCB中,将下个线程TCB中的指令地址指针存放到esp(CPU取值执行所用的寄存器)中

数据库

《MySQL必知必会》《数据库原理,编程与性能》《Redis设计与实现》

数据库

  1. 索引:B树、B+树底层结构,索引失效条件
  2. sql语法
  3. 关系型数据库三范式
  4. 存储引擎:InnoDB和MyISAM对比
  5. 数据库的锁:行锁,表锁,页级锁,意向锁,读锁,写锁,悲观锁,乐观锁等等
  6. 数据库隔离级别,脏读、不可重复读、幻读
  7. 事务的ACID理论
  8. 查询优化:explain,慢查询,show profile
  9. 分布式:分库分表,读写分离
  10. sql乐观锁悲观锁

Redis相关

《Redis设计与实现》

  1. Redis 特点
  2. Redis 底层数据结构:跳表,字典
  3. 数据淘汰策略
  4. 持久化方式:AOF,RDB
  5. 哨兵模式
  6. 集群同步方式

手撕代码

  1. Leetcode石头碰撞问题
  2. 将一整数分别转换成对应的二进制、八进制和十六进制形式
  3. 将两个分数进行相加并化简成最精简的形式,输入的分数形式为"a / b"(除号两边有空格),a和b为正整数。题目
  4. 给一个数组找两个数加起来等于给定数
  5. 字符串最大连续子串
  6. 删除相邻的重复字符。例:acccaef输出为acaef,accaef输出为ef
  7. 字符串解码。例:3[a]2[c]输出为aaaccc,3[a2[c]]输出为accaccacc
  8. 链表节点初始化
  9. int型数字反向输出(注意溢出问题)
  10. 完整实现一个双向链表
  11. 用数组实现深度为100的消息队列,入队出队函数

机考

  1. 方阵旋转
  2. 分礼物
  3. 编辑距离

项目

  1. 需求分析
  2. 并发访问的处理
  3. UML有哪些模型