前言
刚刚经历了3-4两个月的找Java实习的经历,虽然结果并不算完美(只收获几个小厂的offer),但复习准备的经历也算是收获颇丰,更加深刻的理解了Java相关的源码知识,能够静下心来研究平常不会去考虑的JVM,并发编程等知识,经历过这样的复习后能够更加认识到理论知识的重要性。
分类
Java面试题大体有如下几大类:
- JDK源码
- 数据库
- JVM
- Java并发编程
- Spring框架
- 计算机网络
- 算法
- Linux命令(个人没怎么复习,所以本文不考虑)
- Redis(可选)
- 消息中间件,如rabbitmq(可选)
注:一些比较基础的如java知识,面向对象,多态等概念并未列出,还有操作系统原理知识点并不常被问到,也没列出(也是由于这些知识点多采用书本的方式复习,并未整理。。)。
JDK源码
HashMap:(重点:HashMap的数组+链表+红黑树的含义,hash如何定位到对应的数组下标,put()和resize()的过程)
- HashMap源码解析:https://blog.csdn.net/m0_37914588/article/details/82287191
- HashMap面试题:https://www.cnblogs.com/zengcongcong/p/11295349.html
- HashMap链表转红黑树时机:https://www.cnblogs.com/wangflower/p/12235595.html
ArrayList、LinkedList:(源码比较简单,重点:两者内部的数据结构,以及优缺点(增删查改的性能))
- ArrayList源码分析:https://blog.csdn.net/augfun/article/details/82323164
- LinkedList源码分析:https://blog.csdn.net/m0_37884977/article/details/80467658
String相关(相对较简单,重点:String结合字符串常量池理解,StringBuilder和StringBuffer)
- StringBuilder源码分析:https://blog.csdn.net/u012317510/article/details/83721250
- String为什么设计为不可变类型:https://blog.csdn.net/renfufei/article/details/16808775
- String源码分析:https://blog.csdn.net/sun_shaoping/article/details/82079354
- String.intern()
- String的‘+’:采用StringBuilder()来完成。
包装类(以Integer为例,常作为笔试题来出。重点:Integer.valueOf() (内部缓存),Integer.stringSize())
- Integer源码解析:https://blog.csdn.net/JavaZWT/article/details/81587333
- Integer与int(Integer笔试题):https://www.cnblogs.com/demingblog/p/5626824.html
Java代理
- Java原生动态代理及源码(通过和被代理类实现相同接口,动态生成代理对象的字节码文件$Proxy0.class):https://www.jianshu.com/p/9bcac608c714
- CGlib代理:通过继承实现(子类可以重写,增强父类的方法):https://blog.csdn.net/flyfeifei66/article/details/81481222
其他杂乱知识点
- 深拷贝与浅拷贝以及实现深拷贝:https://blog.csdn.net/caoxiaohong1005/article/details/78704890
- Class.forName()和ClassLoader.loadClass()区别:https://www.cnblogs.com/zabulon/p/5826610.html
- Java NIO(开头提到的两篇文章也都值得看):https://blog.csdn.net/forezp/article/details/88414741
- 在Java中定义一个不做事且没有参数的构造方法的作用:Java 程序在执行子类的构造方法之前,如果没有用
super()
来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用 super()
来调用父类中特定的构造方法,则编译时将发生错误,因为 Java 程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。
- HashSet如何检查重复:当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与该位置其他已经加入的对象的 hashcode 值作比较,如果没有相符的 hashcode,HashSet 会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用
equals()
方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
数据库
本文主要介绍mysql相关知识点,以及mysql的InnoDB。引擎的数据库知识主要分为数据库原理,sql语句,数据库引擎细节,sql多为知识点多,多为实操,本文不做介绍(之前美团面试有问到)。数据库原理知识大多数数据库原理教程讲的都大同小异,数据库引擎介绍,我使用的是《MySQL技术内幕(InnoDB存储引擎)第2版》,此书讲的非常清晰易懂,强推!
- InnoDB引擎:mysql数据库(InnoDB引擎)笔记
- 数据库面试题:https://www.cnblogs.com/wenxiaofei/p/9853682.html
- 数据库原理解析:https://blog.csdn.net/qq_17312239/article/details/80825121
- Mysql实现可重复读:https://www.cnblogs.com/lmj612/p/10598971.html
- InnoDB和MyISAM引擎的区别:https://blog.csdn.net/qq_27607965/article/details/79925288
- MySQL预编译语句:https://www.cnblogs.com/micrari/p/7112781.html
- MySQL优化规范建议:https://mp.weixin.qq.com/s__biz=Mzg2OTA0Njk0OA==&mid=2247485117&idx=1&sn=92361755b7c3de488b415ec4c5f46d73
JVM
关于JVM,我主要看的是周志明的深入理解Java虚拟机,基本认真看了这本书就能应付绝大多数jvm面试问题了。下边贴出整理笔记
JVM笔记:深入理解Java虚拟机 笔记
Java并发编程
Java并发编程主要考点在于锁机制,重点Lock和synchronized,另外JUC包下的类,线程池,ThreadLocal也经常会问。也有问实操(给一个场景,分析可能的并发问题,采用什么手段来解决。这个最麻烦,不是简单背书能解决)。Java并发编程推荐一本入门数据《实战Java高并发程序设计(第2版)》葛一鸣著,讲的通俗易懂,读起来很轻松,缺点也在于不够深入。可以读读下边的博客加以补充。推荐一个学习并发编程的网站(http://ifeve.com/),有许多权威并发编程文章的译文。
笔记:实战Java高并发程序设计(第2版)
锁
- Synchronized关键字底层原理:https://blog.csdn.net/javazejian/article/details/72828483
- ReentrantLock源码解析:https://www.cnblogs.com/takumicx/p/9402021.html
ThreadLocal
- ThreadLocal源码解析:https://www.jianshu.com/p/3c5d7f09dfbd
- ThreadLocal内存泄漏问题:https://blog.csdn.net/puppylpg/article/details/80433271
- 1为什么key是弱引用value是强引用
- 2 ThreadLocal最佳实践
- 3 ThreadLocal与线程池共用的问题
- 真实项目中的ThreadLocal使用:https://blog.csdn.net/chunaopan4255/article/details/100897981
- 父子线程传值问题(InheritableThreadLocal):https://www.cnblogs.com/tracer-dhy/p/11404666.html
volatile
- Java内存模型(Java产生同步问题的具体原因):https://www.jianshu.com/p/15106e9c4bf3
- 关于volatile关键字的实现细节:内存屏障:https://www.jianshu.com/p/08a0a8c984ab
- 并发环境下指令重排引起的问题:https://www.jianshu.com/p/90429f2a2aed
- volatile变量使用细节:可以将对volatile变量的读写理解为一个触发刷新的操作,写入volatile变量时,线程中的所有变量也都会触发写入主存。而读取volatile变量时,也同样会触发线程中所有变量从主存中重新读取。因此,应当尽量将volatile的写入操作放在最后,而将volatile的读取放在最前,这样就能连带将其他变量也进行刷新。
- volatile变量使用前提:变量的新值写入不能依赖于变量的旧值,因为根据旧值来计算新值的过程可能出现竞态问题,多个线程同时读取变量的同一个最新值,之后变量的修改操作将会发生覆盖。
Java线程池
- Java线程池简单剖析:https://baijiahao.baidu.com/s?id=1641469444994560637
- Java线程池ThreadPoolExecutor实现源码:https://www.jianshu.com/p/87bff5cc8d8c
- Java线程池设置优先级的简单方式:https://blog.csdn.net/weixin_42440768/article/details/85333954
其他杂乱知识点
- Callable和Runnable的区别https://blog.csdn.net/MrHamster/article/details/89891145
- CopyOnWriteArrayList源码解析(结合开头提到的文章一起看):https://www.cnblogs.com/myseries/p/10877420.html
- ConcurrentHashMap
- JUC原子类以及ABA问题
- 创建线程的方式
Spring框架
spring框架主要问基本概念和源码(一般问源码的并不多),Spring相关有许多附加知识点,JPA,MyBatis,Hibernate等,由于部分并未整理不做介绍。
- Spring IOC源码解析(详细到看不下去):https://blog.csdn.net/nuomizhende45/article/details/81158383
- Spring 解决循环依赖:https://blog.csdn.net/qq_36381855/article/details/79752689
- Spring Bean生命周期:https://www.jianshu.com/p/1dec08d290c1
- @Autowire和@Resource: https://blog.csdn.net/magi1201/article/details/82590106
- @Autowire注入原理:https://blog.csdn.net/weixin_40444222/article/details/95932225
- @Component和@Bean的区别:https://snailclimb.gitee.io/javaguide-interview/#/./docs/e-1spring?id=component-%e5%92%8c-bean-%e7%9a%84%e5%8c%ba%e5%88%ab%e6%98%af%e4%bb%80%e4%b9%88%ef%bc%9f
- Spring事务传播机制:https://blog.csdn.net/li396864285/article/details/75098303
- SpringBoot自动配置:https://blog.csdn.net/u014745069/article/details/83820511
- Spring @Transactional注解解析:https://blog.csdn.net/yangquanwa/article/details/88578357
计算机网络
计算机网络主要看书,如《计算机网络 第七版》谢希仁著。一般主要考察TCP,HTTP相关知识点。
- HTTP协议:https://www.cnblogs.com/an-wen/p/11180076.html
- HTTP与HTTPS比较:https://blog.csdn.net/xiaoming100001/article/details/81109617
- HTTP请求的缓存机制:https://www.cnblogs.com/smallKilts/p/10916931.html
- HTTPS协议详解:https://www.cnblogs.com/fecommunity/p/11965870.html
- TCP三次握手较正确的原因:https://blog.csdn.net/lengxiao1993/article/details/82771768
Redis
- Redis分布式锁:https://blog.csdn.net/yb223731/article/details/90349502
- Redis内存淘汰机制:https://www.jianshu.com/p/b1b4eeccc140
- Redis槽点:https://www.cnblogs.com/php-linux/p/11457317.html
- Redis缓存击穿,缓存穿透,缓存雪崩:https://www.jianshu.com/p/b57d0773ee96
- 布隆过滤器:https://www.jianshu.com/p/2104d11ee0a2
RabbitMQ
- RabbitMQ介绍:https://blog.csdn.net/liuensong/article/details/103538985
- 消息队列如何保证消息不被重复接收(简单看):https://blog.csdn.net/ikownyou/article/details/88065709
- Rabbitmq保证可靠传输:https://www.cnblogs.com/mengchunchen/p/10020488.html
- Rabbitmq保证消息的顺序性:https://www.cnblogs.com/doit8791/p/10340482.html
算法
基本面试必写的算法,具体自行leetcode刷题(dfs解决一切hh)。本节只列举自己整理的可能口述的算法题
- 排序算法(图解):https://www.cnblogs.com/onepixel/articles/7674659.html
- 简单约瑟夫环问题:https://blog.csdn.net/dongyanwen6036/article/details/84892590
- 100亿个数里找最大的前K个数: https://blog.csdn.net/sophia__yu/article/details/80216369
- 100本书,两个人拿,一次只能拿1~5本,你先拿,问怎么保证最后一本一定是你拿到:https://www.jianshu.com/p/42fa9fcccade
- 剪绳子:https://blog.csdn.net/yl_puyu/article/details/104497699
- 64匹马,8个赛道,找出前4名最少比赛多少场?:https://www.cnblogs.com/reanote/p/find_4th_in_64horse.html
其他杂乱的知识点
伪共享和缓存行:https://www.jianshu.com/p/7f89650367b8
字节码角度分析i++和++i: https://www.jianshu.com/p/7988e646a37e
Java高并发系统的限流策略:https://blog.csdn.net/abc592328292/article/details/80295837
Java Lambda表达式实现原理:https://blog.csdn.net/jiankunking/article/details/79825928
Java8 Stream API详解:https://blog.csdn.net/justloveyou_/article/details/79562574
几个推荐的他人优秀的复习整理:
美团面试题:https://github.com/Snailclimb/JavaGuide/blob/master/docs/essential-content-for-interview/PreparingForInterview/%E7%BE%8E%E5%9B%A2%E9%9D%A2%E8%AF%95%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93.md#21-%E4%B8%A4%E8%80%85%E7%9A%84%E5%AF%B9%E6%AF%94
常见面试题总结:https://crossoverjie.top/JCSprout/#/
JavaGuide:https://snailclimb.gitee.io/javaguide/#/
敖丙:https://github.com/AobingJava/JavaFamily