Java后端开发面试题总结

461 阅读12分钟

前言

多次面试中遇到的自己比较记忆深刻,但是不太会的问题,做一个总结,持续更新...


鼠鼠我五月初才开始全力准备找实习,然后5月18号投递,陆续开始面试,因为准备时间短,深度和广度都达不到,并且没什么做的很透的项目,所以感觉暑期实习有点无望。

这里总结一下最近面试中遇到的一些比较印象深刻的问题,希望大家共勉。

我的想法是,大家可以直接在评论区作答,然后互相交流一下,然后后期可以出一个提供答案的版本。

个人感悟:我们看八股文的时候能看懂的程度远远不够,因为很多内容光解释清楚就得写上千字,因此回答需要精简有力,让面试官体会到你是理解且懂的,这需要很高的融会贯通和语言表达能力。因此在回答问题的时候,尽量按照面试时候可能的回答来练习,希望不要直接复制粘贴一大段或者一篇文章,当然可以给好文章的链接。

面试题

  1. synchronized优化有哪些?
  2. 红黑树为什么比平衡二叉树更优,差别主要在哪?
  3. Java垃圾回收机制安全点SafePoint了解吗?
  4. Spring框架中,一个http请求打到Controller上的流程是什么,请求的生命周期或者处理流程?
  5. Spring中Java Bean的生命周期
  6. 在SpringBoot项目中,如何使用Redis的zset实现一个排行榜
  7. 你对函数式编程有什么了解?
  8. TCP/IP的七层结构分别是什么,每一层的功能是什么?
  9. Maven是干什么的?
  10. 讲一讲进程和线程的区别?协程了解吗?
  11. 谈谈你对JVM的理解
  12. 谈谈你对堆和栈的认识和理解?
  13. 假如我在函数体内,创建了一个变量Integer a,它是在栈上还是在堆上?
  14. JVM垃圾回收的流程讲一下
  15. 讲一下类加载机制。
  16. http状态码有哪些?301和302有什么区别,501、502、503、504有什么区别?
  17. 对象头了解吗,对象头、实例数据、对齐填充。
  18. InnoDB是如何解决幻读问题的?(Next-Key锁:间隙锁+行锁)
  19. 有一个微博大V,它发送一条消息,如何将这条消息推送到每个关注他的用户?(读扩散、写扩散问题)
  20. 线程池核心线程会回收吗,比如核心线程数是2,最大线程数5,我创建了一个线程,执行完毕后这个线程会回收吗?
  21. 如果有很大的并发量,但是每个线程的执行时间都很短,使用什么线程池比较合适?
  22. HashMap中使用拉链法/红黑树来处理哈希冲突,什么时候链表变换为红黑树,红黑树是否会收缩为链表?
  23. Netty的IO多路复用是如何实现的,讲一下!
  24. 为什么Redis使用单线程?
  25. 垃圾回收器有哪些?CMS垃圾回收器的过程。如果你设计或选择一个垃圾回收器,你需要考虑哪些问题?
  26. CAP了解吗,Spring Cloud呢?
  27. 详细介绍一下类加载的过程。
  28. MySQL数据库事物的四个隔离级别,是如何实现可重复读的(MVCC),具体如何实现的?
  29. 我们实现一个审批系统,经销商会提交审批清单,会有多个管理员同时进行审批,如何保证管理员审批的清单不会出现冲突,你会如何设计?
  30. Java的一个特点是支持多线程,难道C/C++不支持么?有什么区别?
  31. 方法重载在JVM层是如何实现的?
  32. CPU的三级缓存了解吗?
  33. NIO和AIO的本质区别是什么?
  34. synchronized是如何保证原子性的?(执行synchronized时,对应lock原子操作会刷新工作内存中共享变量的值)
  35. synchronized是如何保证可见性的?
  36. synchronized是如何保证有序性的?(加synchronized之后,依然会发生重排序,只不过,我们有同步代码块,可以保证一个线程执行同步代码中的代码,保证有序性)
  37. synchronized是可中断的吗?
  38. synchronized出现异常会释放锁吗?(会释放锁)
  39. synchronized和Lock的区别是是什么?
  40. 为什么说之前版本的synchronized是重量级锁?
  41. 一个请求发送到Controller,然后调用Service,执行了方法A,而方法A调用了方法B,方法B是被AOP增强的方法,假如方法B执行失败,抛出异常,是否会回滚?
  42. 一个MySQL数据表,有一个列为a,并建立了索引,里面存储数据1到10,假如我执行SQL语句select * from table where str(a)='3',是否会执行成功,是否会走索引,执行过程和结果是什么?
  43. 在SpringBoot中@EnableAutoConfiguration是如何实现自动配置的?
  44. 如何解决分布式Session问题?
  45. 多线程问题,两个子线程轮流打印。
  46. Redis是怎么实现内存优化的?
  47. jdk1.7到1.8有哪些变化?
  48. 谈谈你对tcp粘包的理解,如何解决这种问题?
  49. 你作为学生会主席,你觉得相对于其他人你有什么优势?
  50. 你在写项目的过程中,遇到过哪些困难,有没有这样的case,你是怎么解决的?
  51. netty有了解吗,谈谈你的理解?
  52. 现在用户登陆都是使用邮箱登陆或者手机号登陆,谈谈整个实现过程?
  53. 如何传输大文件?
  54. 为什么要使用LocalDate、LocalTime或LocalDateTime?
  55. 在使用MySQL语句中,使用order by desc的效率怎么样,有没有优化的方法?
  56. 序列化和反序列化有了解吗,你有使用过哪些序列化工具吗?
  57. ConcurrentHashMap是线程安全版本的HashMap,为什么HashMap允许插入null的key和value,而ConcurrentHashMap不允许插入null的key和value,为什么会这样设计,谈谈你的理解?此外,ConcurrentHashMap是线程安全的,在多线程情况下一定没有问题吗?从CAP理论角度探讨这个问题。
  58. volatile底层是如何实现的?
  59. 说明一下浏览器中输入URL执行流程?
  60. 你了解WebSocket协议吗?
  61. https中的s是什么意思,可以详细说一下过程吗,以及为什么要这么设计,谈谈你的理解?
  62. 你对线程池的理解,为什么要使用线程池?

题目答案

待补充...

  1. synchronized优化有哪些? synchronized是JDK的一个关键字,JDK6对其进行了一个较大的优化,包括偏向锁、轻量级锁、(重量级锁)、锁粗化、锁消除、自旋锁。

  2. synchronized和Lock的区别是是什么?

  • synchronized是关键字,而Lock是一个接口
  • synchronized会自动释放锁,而Lock必须手动释放锁
  • synchronized是不可中断的,Lock可以中断也可以不中断
  • 通过Lock可以知道线程有没有拿到锁,而synchronized不能
  • synchronized能锁住方法和代码块,而Lock只能锁住代码块
  • Lock可以使用读写锁提高多线程读效率
  • synchronized是非公平锁,而Lock可以实现非公平锁和公平锁
  1. Java垃圾回收机制安全点SafePoint了解吗?
    GC并不是任何时候都能做的,需要代码运行到安全点安全区域才能进行。特定的安全点位置主要有以下几种:
  • 方法返回之前
  • 调用某个方法之后
  • 抛出异常的位置
  • 循环的末尾 当垃圾收集需要中断的线程的时候,不直接对线程操作,仅仅简单设置一个标志位,各个线程执行过程时在上面所说的那些安全点都会检查这个标志,一旦发现中断标志位为真时,就在安全点上主动挂起。
    安全区域就是一个区域内都可以执行垃圾回收的区域。
  1. Spring框架中,一个http请求打到Controller上的流程是什么,请求的生命周期或者处理流程?
    第一,http请求一般是一个域名,需要请求DNS域名服务器解析,转换为IP地址,当然存在本地缓存,则直接取缓存。
    第二,向目标IP地址发送http请求,一般情况下这个http请求是一个反向代理服务器如nginx,nginx需要做负载均衡,将请求转发到特定的目标服务器上(微服务是怎么弄的不太清楚,后续再改进)。
    第三,http请求发送到Web服务器,Web服务器负责解析http请求与返回http响应。
    第四,转发请求到Servlet容器处理,主要组件是一系列的过滤器Filter
    第五,请求转发到Spring容器的DispatcherServlet,找到匹配的HandlerExecutionChain和HandlerAdapter,经过一系列的过滤器Interceptor,然后再打到Controller上。
    第六,执行上述过程的后置操作,整个过程为一个类似于栈的后进先出U形返回过程。

5 Spring中Java Bean的生命周期(待优化)
加载Bean:使用反射机制从特定的文件加载Bean的字节码
实例化Bean:new创建Bean对象,填充属性,初始化,主要涉及一些Bean装配的前置和后置操作
添加到单例池:添加Bean到singleObjets,供全局使用。
销毁:执行销毁的前置方法和销毁方法

  1. 在SpringBoot项目中,如何使用Redis的zset实现一个排行榜
    需要注意的两点:
  • 数据库一致性问题
  • 如何选定zset的key以实现特定时间段内的排行榜
    简单说一下解决措施:
    1)使用版本号机制确保数据库一致性,在MyBatis Plus中可以使用@Version来实现。
    2)始终维护当前时间起,一个小时内的排行榜,维护一个zset,其key为"redis::current",虽有插入数据的过期时间设置为1小时,这样可以保证删除超过一小时的数据缓存。
    3)构建历史排行榜,如近3小时,近24小时,分别创建key为"redis::three-hours"和"redis::one-day",每次整点时刻,将key为"redis::current"的zset的数据添加到"redis::three-hours"和"redis::one-day"的zset中,并设置过期时间分别增加2小时和23小时。
    4)这样,每次查询排行榜时,调用ZREVRANGE查看排行榜即可。
    具体实现见SpringBoot项目代码。
  1. 你对函数式编程有什么了解?
    Java中的lambda表达式,stream()流式计算

  2. TCP/IP的七层结构分别是什么,每一层的功能是什么?

  3. 有一个微博大V,它发送一条消息,如何将这条消息推送到每个关注他的用户?(读扩散、写扩散问题)
    这里有两个博客记录了聊天软件的设计方案,涉及到该问题。
    IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)
    读扩散,写扩散,终于讲清楚了!

  4. 线程池核心线程会回收吗,比如核心线程数是2,最大线程数5,我创建了一个线程,执行完毕后这个线程会回收吗?此时重新提交一个线程任务,如何执行?
    核心线程不会回收,此时新提交一个任务,由于当前线程池中的线程数量小于核心线程数,会创建新的线程来执行最近提交的任务。

  5. HashMap中使用拉链法/红黑树来处理哈希冲突,什么时候链表变换为红黑树,红黑树是否会收缩为链表?
    有两种情况可能出发红黑树退化为链表:

  • 扩容时resize()时,如果红黑树中节点的数量小于等于6,则退化为链表
  • 移除元素remove()时,判断红黑树根为空或红黑树根左/右子树为空,或左子树的左子树为空,则退化为链表
  1. 为什么说之前版本的synchronized是重量级锁?
    加锁存在用户态和内核态切换。

  2. 谈谈你对tcp粘包的理解,如何解决这种问题?(待补充) tcp是一个流式透明传输的协议,对于一个tcp链接,发送端将多个数据包如a、b和c连续发送到接收端,在tcp传输中是无差别的字节流传输,接收端无法区分出数据包a、b和c的,这样接收到的数据包就无法正常使用,这就是粘包问题。粘包问题不是tcp协议本身的问题,而是上层协议或程序员的工作,需要区分数据包的间隔,将传输层的数据包正确解析出来。
    解决方案有以下:

  • 使用标准的应用层协议(http https)来封装要传输的不定长的数据包。
  • 在每条数据的尾部添加特殊字符,如果遇到特殊字符,代表当条数据接收完毕。
  • 在发送数据块之前,在数据块最前边添加一个固定大小的数据头,这时候数据由两部分组成:数据头+数据块
  1. 说明一下浏览器中输入URL执行流程?
graph TD
解析协议 --> 解析域名
解析域名 --> 解析端口号
解析端口号 --> 解析路径
解析路径 --> 传递查询字符串
传递查询字符串 --> 解析锚点
解析锚点 --> 请求资源
请求资源 --> 接收资源