目录
这是一份来自哔哩哔哩的Java面试
课程预习
1.1 课程内容分为三个模块
基础模块:
- 技术岗位与面试
- 计算机基础
- JVM原理
- 多线程
- 设计模式
- 数据结构与算法
应用模块:
- 常用工具集
- 常用框架
- 缓存
- 队列
- 数据库
综合模块:
- 系统架构设计
- 微服务架构
- 容器化
1.2 换工作面临问题
能力不错,却总被忽略
- 不知道简历怎么准备
- 工作年限
- 美观度
- 多分简历
- 不知道面试官考什么
- 社交门户侧重于大规模并发场景的应用和架构能力
- OTO行业侧重于综合能力考察
- 金融更喜欢逻辑缜密,对高可用安全领域有经验的候选人
- 校招更多对基础知识和逻辑思维方面的考察,以培养潜力考察为主
- 初中级工程师则需要多关注知识的广度,基础知识的应用
- 高级资深工程师需要深入理解基本原理,以综合能力考察为主
- 没有get到面试官的考察意图。如:问到是否使用某框架,实际是是问该框架的使用场景,有什么特点,和同类可框架对比一系列的问题。
- 不知道如何提升晋级?
- 学习首先有个框架
1.3 课程特色
- 全盘汇总:Java知识体现精细梳理
- 特近实战:面试官亲自教你拿Offer
- 潜规则:揭秘技术面试加分&潜规则
- 权威性:拉勾40W技术岗位大数据支持
课时1:技术人职业发展路径
1.1 工程师发展路径
技术序列:技术攻坚、架构知识、专业知识
- 工程师
- 高级工程师
- 资深工程师
- 技术专家
- 高级技术专家
1~3年内从工程师到高级工程师发展,夯实基础,重点提高工作基础能力,培养技术的深度和广度,对不同方向的新技术保持强烈的好奇心和学习心
3年以上资深工程师需要重点配音技术攻坚能力,疑难问题的排查,大型项目的工程拆分,技术品牌的塑造。具体工作包括,原理实现,注重框架能力的培养,大规模高并发场景,高可用可扩展措施和方案,业务的抽象和架构能力
管理序列:团队管理、项目管理、沟通协作
- 工程师
- 高级工程师
- 技术经理
- 技术总监
- 高级技术总监
偏向于团队把控,需要让团队形成技术战斗力,利用一切资源让团队完成作战目标,做好团队内和跨团队沟通工作,在实际工作中这两种并没有明显的边界,例如做管理不表示远离架构设计,技术专家也不是单兵作战。这两个方向的区分点在于工作方向的侧重点不同。
面试诀窍示例:同过往的经验来看,我对项目的整体规划、管理、推进比较感兴趣,在任务协调沟通方面也有过比较突出的表现,所以我的职业规划是成为一名职业的技术经理,以管理方向为发展目标。
1.2 常见技术岗位划分
职级 | 工作年限 | B(百度) | A(阿里) | T(腾讯) |
---|---|---|---|---|
高级技术专家 | 5-10 | T7 | P8 | |
技术专家 | 4~8年 | T6 | P | |
资深工程师 | 3~6年 | T5 | P | |
高级工程师 | 2~4年 | T4 | ||
工程师 | 1~3年 |
1.3 面试岗位选择
公司&团队
- 大公司核心业务(首选)
- 小公司核心业务(1~3年)
- 大公司边缘业务(镀金)
- 小公司边缘业务(尽量不选)
岗位匹配度
匹配度与发展方向相吻合
1.4 常见面试流程
- 前置面试
- 电话面试
- 笔试
- 上机编程
- 技术一面
- 纯技术面(首选算法,例如排序、)
- 偏重于基础与实战能力
- 面试官是未来的同组同事
- 技术二面
- 纯技术面(项目能力、架构能力)
- 偏重算法、技术深度
- 面试官是未来直属leader
- 技术三面
- 半技术面(架构能力、技术敏感度、职业规划)
- 架构能力与发展潜力
- 面试官是部门技术leader
- HR面
- 非技术面
- 个人发展规划
- 价值观与薪资
- 各级领导
- 一般非技术面
- 没有原则性问题能都通过
1.5 面试前的准备工作
能力、心态、沟通
- 了解应试公司及岗位信息
- 系统复习基础知识
- 对原公司负责的项目进行梳理总结
- 学习典型架构案例
- 阅读常考考点源码
- 针对性准备加分项
提前准备一份自我介绍,自己的技术特长和职业优势
避免冷场,对于回答不上来的问题,提供解题思路,或者询问面试官是否可以换一个问题
注意细节,坐姿、表情、观察面试官反应
1.6 面试考察点
硬技能
- 基础知识
- 项目经验
- 架构能力
- 应用能力
软实力
- 逻辑思维
- 沟通协作
- 管理推进
- 学习思考
- 培养潜力
1.7 四类硬技能
基础知识
- 计算机基础
- 网络
- 操作系统
- 数据结构
- 算法
- Java
- JVM
- 语言特性
- 多线程
项目经验
- 项目描述
- 项目难点
- 项目问题
- 项目改进
应用知识
- 常用工具
- 排查类
- 协作类
- 保障类
- 系统类
- 常用框架
- Spring
- Netty
- Dubbo
- Motan
- Mybatis
- 队列
- 数据库
- 缓存
架构能力
- 微服务架构
- Docker
- ZK
- SC
- KBs
课时2:计算机与网络基础
- 知识点汇总
- TCP详解
- 设计模式详解
- Java语言基础知识
- 考察点和加分项
- 真题
2.1 知识点汇总
2.1.1操作系统(加粗为重点)
进程与线程
- 区别联系:进程是资源分配的最小单位,线程是程序执行的最小单位;进程使用独立的数据空间,线程共享进程的数据空间
- 线程调度:时间片轮转调度、先来先服务调度、优先级调度、多级反馈队列调度、高响应比优先调度
- 线程切换步骤:线程的上下文切换、线程切换的代价
- Linux下的IPC(进程间通讯)
- Pipe
- MessageQueue
- 共享内存
- UnixSocket
- Signal
- Semaphore
- 协程
Linux常用命令
- awk
- top
- netstat
- grep
- less
- tail
死锁
内存分页管理于Swap
任务队列于CPU Load
扩展知识点
- 内存屏障
- 指令乱序
- 分支预测
- CPU亲和性(affinity)
- Netfilter于iptables
2.1.2 网络知识(加粗为重点)
4/7层网络模型
TCP协议
- 建立链接三次握手
- 关闭链接四次握手
- 报文状态标志与链接状态
- Nagel算法与ACK延迟
- Keepalive
- 滑动窗口与流量控制
UDP
- 非链接
- 非可靠传输
- 效率高
HTTP
- 协议
- Method
- Header
- Cookie
- UrlEncode
- 状态码
- HTTPS
- HTTP2
- 多路复用
- Stream
- 流量控制
- 服务端推送
- 头部压缩
QUIC(基于UDP,但是提供了基于UDP的可靠性保障)
- 避免前序抱阻塞(HOL阻塞)
- 零RTT建联
- FEC前向纠错
2.2 TCP详解
TCP特点
- 基于链接(点对点)
- 双工通信
- 可靠传输
- 拥塞控制
- 基于字节流而非报文(保证数据的可靠性和完整性)
TCP实现细节
- 8种报文状态
- 滑动窗口机制
- KeepAlive
- Bagel算法
2.2.1 三次握手建联
2.2.2 四次挥手断连
2.3 设计模式详解
主要考察两点
- 设计模式的实现
- 设计模式的使用场景(用来解决什么问题)
单例模式
工厂模式
代理模式
构造者模式
责任链模式
适配器模式
观察者模式
其他模式
2.3.1 单例模式线程安全实现
- 静态初始化(饿汉式)
- 双重检查(懒汉式)
- 单例注册表
2.3.2 常用设计模式与应用场景
- 工厂模式:Spring如何创建Bean
- 代理模式:Motan服务的动态代理
- 责任链模式:Netty消息处理的方式
- 适配器模式:Slf4J如何支持Log4J
- 观察者模式:GRPC是如何支持流式请求的
- 构造者模式:PB序列化中的Builder
2.4 Java基础知识详解
JUC
- ConcurrentXXX
- AtomicXXX
- Executor
- Caller&Future
- Queue
- Locks
版本差异新特性
动态代理与反射
数据类型
- 空间占用
- 基本数据结构
- 自动转型与强制转型
- 封箱与拆箱
常用集合
- HashMap
- ConcurrentHashMap
- ArrayList&LinkedList
- HashSet
- TreeMap
对象引用
- 强引用
- 弱引用
- 软引用
- 虚引用
异常机制
扩展知识点
- SPI机制
- 注解处理机制
2.4.1 Map——知识点详解
HashMap
- 数组加链表的实现方式
- 容量大小是2的幂次方
- 并发读写会有什么风险
ConcurrentHashMap
- 并发控制与分段锁思想
- 1.8中的CAS自旋锁
- 红黑树的启用条件
2.4.1 Java版本特性
V 1.8
- Lambda表达式
- Stream API
- 方法引用
- 接口默认方法
- Metaspace替换PermGen
V 1.9-1.10
- 模块系统
- 默认G1回收器
- 接口私有方法
- 局部变量推断
- Graal编译器
V 1.11
- ZGC
- 字符串API增强
- 内建HTTP Client
2.5 考察点和加分项
面试考察点
- 基本概念和基本原理
- 实现方式与使用姿势
- 经常用到的知识点
- 实际应用中容易犯错的点
- 与面试方向相关的知识点
加分项
- 知识点与典型的业务场景关联
- 以反例来描述实际场景中误用的危害
- 与知识点相关的优化点(例如在介绍TCP的建联与断连时最好能够指出,出现timewait时可以调整系统参数加快链接的回收与复用)
- 与知识点相关的最新技术趋势
- 在了解的前提下,尽量增加回答内容深度
2.6 真题
真题汇总——1
- 线程与进程的区别与联系
从资源的占用,切换效率,通信方式回答 - 简单介绍一下进程的切换过程
主要考察线程上下文的切换代价,要回答切换会保持寄存器、栈等线程相关的现场,需要由用户态切换到内核态,最后知道可以通过vmstate命令查看上下文的切换状况 - 你经常使用哪些Linux命令,主要用来解决什么问题?
- 为什么TCP建联需要3次握手而断连需要4次
- 为什么TCP关闭链接时需要TIME_WAIT状态,为什么要等2MSL?
- 一次完整的HTTP请求过程是怎样的
DNS解析、TCP建联、HTTP请求、HTTP相应
真题汇总——2
- HTTP2与HTTP的区别有哪些?
- 在你的项目中你使用过哪些设计模式?主要用来解决什么问题?
- Object中的equal和hashCode的作用分别是什么?
- final、finally、finalize的区别与使用场景
- 简单描述一下java的异常机制
- 线上使用的哪个版本jdk,为什么使用这个版本(有什么特点)?
课时3:深入浅出JVM
3.1 知识点汇总
内存模型
- 程序计数器
- 方法区
- 堆
- 栈
- 本地方法栈
类加载器
- 双亲委派机制
- Boostrap类加载器
- Extension类加载器
- System类加载器
- 自定义类加载器
GC
- 分代回收
- 老年代
- 年轻代
- 持久代
- 回收器实现
- 穿行回收器
- 并行回收器
- CMS
- G1
性能调优
- JVM参数
- 性能分析工具
- MAT
- JMC
- JStack
- JStat
执行模式
- 解释模式
- 编译模式
- 混合模式
编译器优化
- 公共子表达式的消除
- 指令重排
- 内联
- 逃逸分析
- 方法逃逸
- 线程逃逸
- 栈上分配
- 同步消除
3.2 JVM的内存模型
3.2.1 JVM内存模型
线程独占
- 栈(存储局部变量表、操作栈、动态链接、方法出口等信息)
- 本地方法栈(native方法)
- 程序计数器
线程共享
堆(堆所有线程共享,分代管理)
方法区(类信息、常量、静态变量,jdk1.7中的永久代和jdk1.8中的metaspace都是方法区的一种实现)
面试回答要点:
- 各部分功能
- 哪些是线程共享,哪些是线程独占
3.2.2 JMM与内存可见性
Java内存模型,定义程序中变量的访问规则。
在多线程进行数据交互时,例如线程A给一个共享变量赋值后由线程B来读取这个值,线程A修改变量只修改在自己的工作内存区中,线程B是不可见的,只有从A的工作内存区写回到工作主内存,B在从主内存读取到自己的工作内存区才能进行进一步的操作。
由于指令重排序的存在,写和读的顺序可能会被打乱,因此JMM需要提供原子性、可见性、有序性的保证。
3.2.3 JMM保证
3.3 Java类加载机制详解
3.3.1 类的生命周期
加载:是文件到内存的过程,通过类的完全限定名查找此类字节码文件,并利用字节码文件创建一个Class对象;
验证:验证是堆文件类内容验证,目的在于当前类文件是否符合虚拟机的要求,不会危害到虚拟机安全,主要包括四种:文件格式验证、元数据验证、字节码、符号引用;
准备:准备阶段是进行内存分配,为类变量,也就是类中由static修饰的变量分配内存并设置初始值,初始值是0或null,而不是代码中设置的具体值,代码中设置的值在初始化阶段完成,另外也不包括final修饰的静态变量,因为final变量在编译时就已经分配;
解析:解析主要是解析字段、接口、方法,主要是将常量值中的符号引用替换为直接引用的过程,直接引用就是直接指向目标的指针或相对偏移量等;
初始化:最后是初始化,主要是完成静态块执行与静态变量的赋值,这是类加载最后阶段,若被加载类的父类没有初始化,则先对父类进行初始化。
只有对类使用是才会初始化,初始化的条件包括访问类的实例,访问类的静态方法和静态变量的时候,使用Class.forName()
反射类的时候,或者某个子类被初始化的时候。
图中浅绿的两个部分表示类的生命周期。
3.3.2 类加载器
BootStrap ClassLoader
:启动类加载器加载JAVA_HOME/lib
下的类
ExtClassLoader
:扩展加载器加载JAVA_HOME/lib/ext
下的类
AppClassLoader
:应用加载器加载加载classpath
指定目录下的类
除此之外,还可以自定义类加载器。
Java的类加载器使用双亲委派模式,双亲委派模型的工作过程是:
- 如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。
- 每一个层次的类加载器都是如此。因此,所有的加载请求最终都应该传送到顶层的启动类加载器中。
- 只有当父加载器反馈自己无法完成这个加载请求时(搜索范围中没有找到所需的类),子加载器才会尝试自己去加载。
很多人对“双亲”一词很困惑。这是翻译的锅,,,“双亲”只是“parents”的直译,实际上并不表示汉语中的父母双亲,而是一代一代很多parent,即parents。
双亲委派模式优势:
采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader
再加载一次。其次是考虑到安全因素,java核心api中定义类型不会被随意替换,假设通过网络传递一个名为java.lang.Integer
的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的java.lang.Integer
,而直接返回已加载过的Integer.class,这样便可以防止核心API库被随意篡改。
3.4 常用GC算法介绍
3.4.1 分代回收
分代管理主要是为了方便垃圾回收,这样做是基于两个事实:
- 大部分对象很快都不在使用
- 还有一部分不会立即无用,但也不会持续很长时间
大部分对象在Eden区中生成,Eden区满时,还存活的对象会在两个Suivivor区交替保存,达到一定次数后对象会晋升为老年代。
老年代用来存放从年轻代晋升而来的存活时间较长的对象。
永久代主要用来保存类信息等内容。
3.4.2 垃圾回收算法
CMS算法——JDK 1.7以前
G1算法——JDK 1.9后默认垃圾回收算法
ZGC——针对大内存堆的低延迟垃圾回收算法
- 着色指针
- 读屏障
- 并发处理
- 基于Region
- 内存压缩(整理)
ZGC算法
3.5 考察点和加分项
考察点
- 深入理解JVM内存模型
- 了解类加载机制
- 了解内存可见性
- 了解常用的GC算法实现和使用场景
- 能够根据业务场景选择合适JVM参数与GC算法
加分项
- 编译器优化
- 问题排查经验与思路
- JVM调优经验与调优思路
- 了解最新的技术趋势(例如:ZGC、Grraalvm)
3.6 真题
- 简述描述一下JVM的内存模型
- 生命情况下会触发FullGC
- Java类加载器由几种,关系是怎样的?
- 双亲委派机制的加载流程是怎样的,有什么好处?
- 1.8为什么用Metaspace替换掉PermGen?Metasapce保存在哪里?
- 编译期会对指令做哪些优化?(简单描述编译器的指令重排)
- 简单描述一下volatile可以解决什么问题?如何做到的?
强制主内存读写同步以及防止指令重排序两点 - 简单描述一下GC的分代回收
- G1垃圾回收算法与CMS的区别有哪些?
- 对象引用有哪几种方式,有什么特点?
强弱软虚在四种引用以及在GC中的处理方式 - 使用过哪些JVM调试工具,主要分析哪些内容?
课时4:并发与多线程
4.1 知识点汇总
死锁
- 竞争条件与临界区
- 死锁检测与防止死锁
- 残剩条件
- 互斥
- 请求并保持
- 不可剥夺
- 循环等待
线程通信
- wait
- notify
- notifyAll
线程状态转换
- NEW
- RUNNABLE
- BLOCKED
- WAITING
- TIMED_WAITING
- TERMINATED
常用工具类(JUC)
- ConcurrentXXX
- AtomicXXX
- Executor
- Caller&Future
- Queue
- Locks
机制
- ThreadLocal
- Fork/Join
- Volatile
- Interrupt
同步与互斥
- Synchronized
- Lock
- 锁类型
- 锁实现
- CAS
- Unsafe
- 原语
线程池
- 使用场景
- 原理与实现方式
- 线程池实现
4.2 线程的状态转换
4.3 线程同步与互斥
CAS与ABA问题
Synchronized实现原理
AQS与Lock
4.4 线程池详解
线程池使用场景
线程池参数介绍
核心线程数,默认情况下,核心线程会一直存活
最大线程数,决定线程池最多可以创建多少线程
线程的空闲时间,空闲时间的单位,当线程闲置超过空闲时间时就会被销毁
线程缓存队列
- 有界队列
- *队列
- 同步队列
线程池工厂方法
线程池满时拒绝策略
- 抛出异常
- 丢弃
- 提交失败时,由提交任务的线程直接执行任务
- 丢弃最早提交的任务
线程池任务执行流程
4.5 JUC重点工具实现类
类名 | 特点 |
---|---|
AtomicLong, AtomicInteger, AtomicBoolean, LongAdder, DoubleAdder, LongAccumulator, DoubleAccumulator | AtomicLong通过unsafe类实现,基于CAS。LongAdder基于Cell,分段锁思想,空间换时间,更适合高并发场景 |
AtomicReference, AtomicStampedReference, AtomicMarkableReference | 原子对象读、写。AtomicStampedReference和AtomicMarkableReference用来解决ABA问题,分别基于时间戳和标记位 |
ReentrantLock, ReentrantReadWriteLock, StampedLock, LockSupport | ReentranLock是独占锁,Semaphore是共享锁。StampedLock是1.8改进的读写锁,CLH乐观锁,防止写饥饿 |
Executors, ForkJoinPool, FutureTask, CmpletableFuture | CompletableFuture支持流式调用,多future组合,可以设置完成时间。ForkJoinPool:分治思想+工作窃取 |
LinkedBlockingDeque, ArrayBlockingQueue | 双端队列,单端队列 |
CountDownLatch, CyclicBarrier, Semaphore | 多线程任务汇总,多线程并发执行,控制并发读(共享锁) |
ConcurrentHashMap, CopyOnWriteArrayList | COW适合读多写少,小数据量,高并发场景 |
4.6 考察点和加分项
考察点
- 理解线程的同步与互斥的原理(临界资源、理解区、自旋锁、偏向锁 、冲入锁、读写锁概念)
- 掌握线程安全相关机制(CAS、Synchronized、ThreadLocal使用弱引用ThreadLocalMap)
- 了解JUC工具的使用场景与实现原理
- 熟悉线程池的原理、使用场景、常用配置
- 理解线程的同步与异步、阻塞与非阻塞(同步与异步的区别是任务是否在同一个线程中执行的 ,阻塞与非阻塞的区别是异步执行任务时线程是不是会阻塞等待结构还是会继续等待后面的逻辑)
加分项
- 结合实际项目经验或实际案例介绍原理
- 解决多线程问题的排查思路与经验
- 熟悉常用的线程分析工具与方法
- 了解Java8堆JUC的增强
- 了解Reactive异步编程思想
4.7 真题
- 如何实现一个生产者与消费者模型?(锁、信号量、线程通信、阻塞队列等)
- 如何理解线程的同步与异步、阻塞与非阻塞?
- 线程池处理任务的流程是怎样的?
- wait与sleep的由什么不同?
1、wait属于Object类,sleep属于Thread类;2、wait会释放对象锁,而sleep不会;3、wait需要在同步块中使用,sleep可以在任何地方使用;4、sleep需要捕获异常、wait不需要。 - Synchronized和ReentranLock有什么不同?
- 读写锁适用于什么场景?ReentrantReadWriteLock是如何实现的?
读写锁适合读并发多,写并发少的场景 - 线程之间如何通信?
wait和notify机制、共享变量Synchronized - 保证线程安全的方法由哪些?
CAS、Synchronized、Lock、ThreadLocal - 如何尽可能提高多线程并发性能?
尽量减少临界区范围、使用ThreadLocal、减少线程切换、使用读写锁或CopyOnWrite机制 - ThreadLocal用来解决什么问题?ThreadLocal是如何实现的?
重点回答ThreadLocak不是用来解决多线程共享变量的问题,而是线程数据隔离的问题 - 死锁产生的条件?如何分析是否由线程死锁?
- 在实际工作中遇到过什么样的并发问题,如何发现(排查)并解决的?
课时5:数据结构与算法
5.1 知识点汇总
5.1.1 数据结构
队列
栈
表
- 数组
- 单链表
- 双链表
- 循环链表
- 散列表
图
- 有向图
- 无向图
- 带权图
多叉树
- B、B+树
- 字典树
二叉树
- 平衡二叉树
- 红黑树
- 哈夫曼树
- 堆
5.1.2 算法
常用算法思路
- 分治
- 动态规划
- 贪心
- 回溯
- 分支界定
复杂度
- 时间复杂度
- 空间复杂度
排序
- 插入
- 希尔
- 直插
- 交换
- 冒泡
- 快排
- 选择
- 简单选择
- 堆
- 归并
- 基数
查找
- 二分查找
- 二叉排序树
- B树
- BloomFilter
字符串匹配
- BF算法
- BM算法
- Sundady算法
- KMP算法
- Tire树
5.2 从搜索树到B+树
5.3 字符串匹配
字符串匹配问题
判断给定字符串中的括号是否匹配
解体思路:
1、使用栈
2、遇左括号入栈
3、遇右括号出栈,判断出栈括号是否与右括号成对
字符串匹配问题解题思路
5.4 TopK问题
TopK问题
找出N个数中最小的K个数(N非常大)
TopK变种
从N有序队列中找到最小的K个值
5.5 常用算法适用场景
常用算法介绍
5.6 考察点和加分项
考察点
- 了解基本数据结构与特点
- 表、栈、队列、树需要熟练掌握,深刻理解使用场景(例如红黑树适合搜索,B+树适合索引)
- 了解常用的搜索、排序算法,及复杂度和稳定性
- 了解常用的字符串处理算法
- 能够分析算法实现的复杂度
- 了解常用算法分类,解决问题的思路和解决哪类问题
加分项
- 能够将数据结构与实际使用场景结合(介绍红黑树时结合TreeMap的实现,介绍B+树时结合MySQL的索引)
- 不同算法在业务场景中的应用
- 面对模糊的题目能沟通确认条件和边界
- 书写算法代码前,先讲一下解题思路
- 能够发现解答中的一些问题,给出改进的思路
5.7 真题
题1、题2基础题,必须掌握
- 各种排序算法实现和复杂度、稳定性
- 二叉树的前、中、后序遍历
- 翻转句子中单词的顺序
- 用栈模拟队列(或用队列模拟栈)
- 堆10亿个数进行排序,限制内存位1G
- 去掉(或找出)两个数组中重复的数字
- 将一颗二叉树转换成其镜像
- 确定一个字符串中的括号是否匹配
- 给定一个开始词,一个结束词,一个字典,如何找到从开始词到结束词的最短单词接龙路径
- 如何查找两个二叉树节点的最近公共祖先
课时6:常用工具集
6.1 知识点汇总
团队协作
- Ant
- Maven
- Gradle
- Git
- SVN
质量保证
- Checkstyle
- FindBugs
- SonarQube
压测
- JMeter
- JMH
- AB
- LoadRunner
容器与代理(随着微服务的盛行,Envoy、OpenResty、Kong等API网关的使用也越来越普遍)
- Tomcat
- Jetty
- Nginx
- Envoy
- OpenResty
- Kong
CI/CD
- Gitlab-CI
- Jenkins
- Travis
JVM相关
- JMC(JFR)
- jstack、jmap、jstat
系统分析
- vmstat
- iostat & iotop
- ifstat & iftop
- netstat
- dstat
- strace
- GDB
- lsof
- tcpdump
- traceroute
文档管理
- JavaDoc
- Swagger
网络工具
- PostMan
- WireShark(网络包分析工具)
- Fiddler(只针对HTTP进行抓捕)
- Charies
6.2 JVM工具
JMC
线上调试神奇——btrace
其他常用JVM工具介绍
6.3 Git工作流
Git常用命令
Git常用工作流
6.4 Linux系统分析工具
6.5 考察点和加分项
考察点
- 了解常用JVM分析工具
- 掌握Git的常用操作和工作流
- 了解Linux系统下常用的分析工具
加分项
- 能够主动出击体现知识广度(在描述项目问题主动引出工具)
- 能够体现实战能力
6.6 真题
- 排查JVM问题有哪些常用工具?
- Git合并代码有那两种方法?有什么区别
- Git与SVN有哪些差异?
- 你所在的团队项目开发使用什么样工作流?有什么优点?
课时7:必会框架(上)——Spring全家桶
7.1 知识点汇总
Spring
- Spring Framework
- Spring Boot
- Spring Data
- Spring Cloud
- Sleuth
- Netflix
- Config
- Bus
- Security
Struts
ORM
- Hibernate
- Mybatis
Netty
RPC
- Motan
- Bubbo
- Grpc
其他框架
- Jersey
- RESTEasy
- Shiro
7.2 Spring框架
Spring基本概念
Spring框架组件
机制与实现
AOP
- 动态代理
- 静态代理
PlaceHolder动态替换
- PropertyPlaceholderConfigure
- PropertySourcesPlaceholderConfigure
事务
- 隔离级别
- ISOLATION_DEFAULT
- ISOLATION_READ_UNCOMMITTED
- ISOLATION_READ_COMMITTED
- ISOLATION_REPEATABLE_READ
- ISOLATION_SERIALIZABLE
- 传播行为
- PROPAGATION_REQUIRED
- PROPAGATION_SUPPORTS
- PROPAGATION_MANDATORY
- PROPAGATION_REQUIRED_NEW
- PROPAGATION_NOT_SUPPORTED
- PROPAGATION_NEVER
- PROPAGATION_NESTED
核心接口/类
- ApplicationContext
- BeanFactory
- BeanWrapper
- FactoryBean
scope
- Singleton
- Prototype
- Request
- Session
- Global-session
- Application
- Websocket
事件机制
- ContextRefreshedEvent
- ContextStatedEvent
- ContextStoppedEvent
- ContextClosedEvent
- RequestHandledEvent
Spring应用
类型类
- @Controller
- @service
- @Repository
- @Component
- @Configuration
- @Bean
设置类
- @Required
- @Autowired && @Qualifier
- @Scope
Web类
- @RequestMapping && @GetMapping @ PostMapping
- @PathVariable && @RequestParam
- @RequestBody && @ResponseBody
功能类
- @ImportResource
- @ComponentScan
- @EnableCaching && Cacheable
- @Transactional
- @Aspect && Poincut
- @Scheduled
配置方式
- XML
- 注解
- API
自动装配
- byType
- byName
- constructor
- autodetect
集合属性注入
内部bean
Spring Context初始化流程
Spring 中bean的生命周期
Spring 扩展接口
Spring Boot
课时7:必会框架(下)——RPC与ORM
7.3 Netty与RPC
Netty线程模型
RPC介绍
开源RPC框架介绍
7.4 Mybatis
Mybatis知识点
Mybatis处理流程
7.5 考察点与加分项
考察点
- 掌握Spring的IOC、AOP的概念与实现
- 掌握Spring的Context创建流程和Bean的生命周期
- 了解Spring常用注解的作用与使用方式
- 了解SpringBoot的相关知识点
- 掌握Netty的线程处理模型
- 知道常用RPC框架的特点
- 了解Mybatis、Hibernate的实现原理
加分项
- 阅读过框架源码,了解实现细节及思路
- 除了会应用,还能够理解理念
- 了解最新实现或方向
- 有实际优化经验,例如Nett有性能调优
7.6 真题
- SSH和SSM框架组合的区别是生命?
- 能描述一些Spring Context初始化的整个流程吗?
- 简单介绍一些Bean的生命周期及作用域
- Spring配置中的placeholder占位符是如何替换的?有什么办法可以实现自定义的配置替换?
要答出通过beanFactoryPostProfessal后置处理器进行的替换,如果要自定义处理,可以扩展PropertyPlaceHolderConfigure或者PropertySourcePlaceHolderConfigure来实现 - SpringMVC的工作流程是怎样的?
- Spring如何解决循环依赖?
从构造器循环依赖和setter循环依赖两方面来回答 - Bean的构造方法、@PostConstruct注解、InitializingBean、init-method的执行顺序是怎样的?
- 说说Netty中有哪些重要的对象,它们之间的关系是什么?
- RPC与HTTP的区别是什么,什么场景适合选用RPC,什么场景适合使用HTTP?
在使用方式方面,HTTP使用Client,RPC通过动态代理;从请求模型看,HTTP一般会经过DNS解析,4/7层代理等中间环节,而RPC是点对点直连;从服务治理能力来看,RPC提供丰富的服务治理功能,例如熔断 、负载均衡,HTTP对跨语言处理比较方便 - RPC的交互流程是怎样的?
- 请介绍一下Mybatis的缓存机制
- Mybatis如何配置动态SQL?有哪些动态SQL标签?
课时8:缓存
8.1 知识点汇总
8.2 Memcache
MC内存结构
8.3 Redis
Redis知识点
Redis数据结构
8.4 缓存常见问题
8.5 考察点和加分项
考察点
- 了解缓存的使用场景,不同类型缓存的使用方式
- 掌握MC和Redis的常用命令
- 了解MC的Redis在内存中的存储结构
- 了解MC和Redis的数据失效方式和剔除策略
- 了解Redis的持久化、主从同步与cluster部署的原理
加分项
- 结合使用场景来介绍缓存的使用
- 有过分布式缓存设计和应用经验
- 了解缓存使用中可能产生的问题
- 知道Redis的典型应用场景
- 知道Redis的新特性
8.6 真题
- Redis和Memcache有什么区别?该如何选用
- 你用到过哪些Redis的数据结构?用在什么场景下?
- Redis有哪些持久化方式,分别是什么?
- Redis的过期机制是怎样的?Redis有哪些淘汰策略
- 如何保证Redis的高并发和高可用?
- 如何使用Redis实现延时队列?如何使用Redis实现分布式锁?