天天看点

【Java面试】Java工程师面试知识点前言基础模块

前言

我一直比较好奇,java程序员面试会面试什么呢?

在安卓的面试中,其实也有好多java知识点,问的不多,但有些问的深的话,就会整到JVM,JVM内存模型,Java内存模型,指令优化,线程同步,各种xx原理是怎样。

时常,一搜,就是一本《深入理解Java虚拟机》,《Think In Java》。。。

这让我很困惑,不就是java咩,至于这么难吗?面试官该不是想找大学java老师么?

于是,想找一篇简单,通熟易懂,脉络清晰的java面试文章。我去拉勾,看了张雷大兄弟的《32个java面试知识点》,发现java程序员这年头也不好混哪,成为高级Java软工,起码得掌握如下技能树:

【Java面试】Java工程师面试知识点前言基础模块

图0-1 一颗庞大的Java软工要掌握的知识树

我作为大安卓阵营的工程师表示:

在下佩服。

【Java面试】Java工程师面试知识点前言基础模块

图0-2 一个表情

接下来,我会总结一下大神经过200多家公司的分析,给出的java必考知识点。尤其还有一些真题。

大概分为4篇吧。

基础模块

一 计算机基础

【Java面试】Java工程师面试知识点前言基础模块

图1-1

计算机基础,要考的话是考不完的,还是整一整重点知识。

1.1 TCP特点

  • 基于链接
  • 双工通信
  • 可靠传输
  • 拥塞控制
  • 基于字节流而非报文

1.2 TCP的三次握手

  1. TCP三次握手的过程是怎样的?
【Java面试】Java工程师面试知识点前言基础模块

图1-2 tcp三次握手

提问:泛洪攻击的原理,怎么防治?

Server端发送了ACK,SYN给Client后,Client端没有回复ACK,导致服务端大量的连接,处于SYN_RECIEV状态。对其他的新的连接请求造成影响。

1.3 TCP四次挥手断开连接过程

【Java面试】Java工程师面试知识点前言基础模块

图1-2 一张图表示4次握手

二者的区别:

四次挥手要等待2个MSL原因:
  • 第一要保证TCP协议的全双工链接能够很快关闭
  • 第二要保证这次链接中重复的数据段能够从网络中消失,防止端口被重用的时候,可能会产生数据混淆。

问题:

  1. 为啥是三次握手,不是4次或2次握手?
  2. 为啥是4次挥手,不跟3次握手一样,也弄3次?

一起回答:无论如何,这个交互流程上可以看出,无论是建立链接还是断开连接,都是需要在两个方向上进行,只不过

建连是所有端的

SYN和ACK两个包合并为一次发送

,而

断开链接是两个方向的数据发送的停止时间可能是不同的`,所以无法合并SYN,ACK发送,这就是建立链接的时候,必须要三次握手,而断连的时候呢,必须要四次握手。

二 Java语言特性

2.1 最常考的知识点:

  1. HashMap/CurrrentHashMap区别和联系
    1. HashMap不是线程安全的,CurrrentHashMap是线程安全的。

      注意:

      • 使用 EntrySet ,而不是先拿到Key,再get Value,遍历HashMap效率高。
      • 并发时,如果是1.7版本的HashMap,访问HashMap内容,容易出现链表死循环问题。
    2. HashMap内部实现采用Hash数组+链表数据结构,不加锁,CurrrentHashMap内部采用分段锁机制,分成多个Segment, 相当于多个HashTable, 根据key的hashCode存放在不同Segment。上锁的是HashTable, 所以,当key的hashCode不同时,不会上锁。
  2. HashMap,CurrentHashMap的java 1.7和java1.8版本有什么区别?
    • HashMap 1.7采用array + linklist 数据结构, 1.8采用array + linklist + 红黑树数据结构,查询效率更高
    • CurrentHashMap 1.8其中抛弃了原有的 Segment 分段锁,而采用了 CAS + synchronized 来保证并发安全性

参考:一文了解HashMap和CurrentHashMap区别

  1. Java版本的新特性
    1. V1.8
      • Lambda表达式
      • Stream API
        • 方法引用
      • 接口默认方法
      • Metaspace替换PermGen
    2. V1.9-1.10
      • 模块系统
      • 默认G1回收期
      • 接口私有方法
      • 局部变量推断
      • Graal编译器
    3. V1.11
      • ZGC
      • 字符串API增强
      • 内建 HTTP Client

三 JVM 虚拟机

【Java面试】Java工程师面试知识点前言基础模块

图 3-1 JVM的知识点

3.1 JVM原理

  1. JVM内存模型
    • 线程独占:虚拟机栈,本地方法栈, 程序计数器
    • 线程共享:堆,方法区
【Java面试】Java工程师面试知识点前言基础模块

图 3-2 一个JVM内存模型结构(没截图,自己画了一个)

重要知识点:

以上每个区域的功能要点是什么?

哪些区域是线程共享,哪些是线程独占的?

3.2 JMM内存(区别JVM内存模型)

【Java面试】Java工程师面试知识点前言基础模块

图 3-3 一个JMM内存模型结构

  • 线程独有:工作内存
  • 主内存(可以结合vilatile 关键字的作用:

    内存同步,禁止指令优化

    ,一起服用,效果更佳)

3.3 JMM要保证内存变量的一些特性

  • 原子性
  • 可见性
  • 有序性

3.3.1 如何保证上述特点呢?

  1. 基本数据类型的读写(从主内存中拷贝)
  2. syncrhonized (原理:对象头锁,ACESS_SYNCHRONIZED, MonitorActor, MonitorExit)
  3. volatile (强制变量赋值刷新内存,读取从主内存中获取;保证线程可见性)
  4. happend-before原则
    1. 程序的顺序执行(一个线程保证串行)
    2. 加锁规则-解锁要在再次加锁之前。

3.4 类加载过程

加载到内存 -> 验证(文件的格式,元数据验证,字节码,符号引用)

-》 准备阶段(类变量内存)-> 解析 -> 初始化 -> 使用(实例化)

-> 卸载

这个过程,如果细考,非常的长,建议参考 《深入理解java虚拟机》

3.5 类加载器

BootStrap ClassLoader

| |

ExtClassLoader

| |

AppClassLoader

| |

Custom ClassLoader

重点:双亲委派模式

3.6 JVM 内存回收算法

  • 年轻代 Eden Survivor1 Survivor2
  • 老年代 Tenured
  • 永久代 PermGen/Metaspace

各种垃圾回收算法:

  1. CMS算法:
【Java面试】Java工程师面试知识点前言基础模块

图3-1 标记清除算法的阶段

属于标记清除算法,缺点:内存碎片较多。

  1. G1算法(jvm1.9):
【Java面试】Java工程师面试知识点前言基础模块

保持了高回收率的过程。 G1是逻辑分代,不是物理分代。

  1. ZGC-针对64位系统大内存堆的低延迟垃圾回收算法
  • 着色指针
  • 读屏障
  • 并发处理
  • 基于Region
  • 内存压缩(整理)
  1. 一些加分项:
    • 编译器优化(如何栈分配减少内存的压力,如何编写适合

      内联优化

      的代码)
    • 问题排查经验思路
    • JVM调优经验和调优思路
    • 了解最新的技术趋势。(ZGC, Graalvm)

常问的几个问题:

  1. 简单描述一下JVM的内存模型,可以和JMM对比着讲?
  2. 什么情况下会触发FullGC?
  3. Java类加载器有几种?关系是怎样的?
  4. 双亲委派机制的加载流程是怎样的,有什么好处?
    • 在虚拟机里觉得一个类是不是唯一有两个因素,第一个就是这个类本身,第二个就是加载这个类的类加载 器,如果同一个类由不同的类加载器去加载,在虚拟机看来,这两个类是不同的类。
  5. 1.8为什么使用Metaspace替换掉PermGen?MetaSpace保存在哪?
  6. 编译期会对指令做哪些优化?(简述指令重排)
  7. volatile 可以解决什么问题?如何做到?(防止主内存不同步,阻止指令重新排序)
  8. 简单描述一下GC的分代回收?
  9. G1垃圾回收算法和CMS的区别?
  10. 使用过哪些JVM调试工具,主要分析哪些内容?

    JMC, JStack,JMap,MAT。

四 多线程

【Java面试】Java工程师面试知识点前言基础模块
  1. 线程的几种状态
  2. 线程的同步与互斥
    • CAS(乐观锁)与ABA
    • synchronized实现原理
      1. (ACC_SYNCHRONIZED) 方法同步
      2. 代码块同步 monitorenter, monitorexit
      3. 获取锁的方式,锁优化:偏向锁,轻量级锁,自旋锁
      4. 对象头有个Monitor对象,包含_EnterList进入线程队列, Owner, _WaitSet等待队列)

        https://www.cnblogs.com/paddix/p/5367116.html

    • AQS 与 Lock
  3. 线程池的几种类型
    • newFixedThreadPool - 固定线程数,无界队列,适用于任务数量不均匀的场景,对内存压力不敏感,但系统负载比较敏感的场景
    • newCachedThreadPool - 无限线程数,适用于对延迟要求较低的任务场景
    • newSingleThreadPool - 单个线程的固定线程池,适用于保证一步任务顺序执行的场景
    • newScheduledThreadPool - 适用于定期执行任务场景,支持固定频率和固定延时
    • newWorkStealingPool - 使用ForkJoinPool,多任务队列的固定并行,任务执行时长不均匀的场景
    常问的几个问题,真题汇总:
    1. 如何实现生产者与消费者模型(锁,信号量,线程通信,阻塞队列)
    2. 如何理解线程的同步与异步,阻塞与非阻塞?
    3. 线程池处理任务的流程是怎样的?
    4. wait和sleep有什么不同?
      • wait属于object对象,sleep()属于Thread对象
      • wait()会释放对象锁,sleep()不会
      • wait()出现在同步块中, sleep()可以在任何对象中
      • wait()不需要捕获异常,sleep()需要捕获异常
    5. synchronized

      ReetrantLock

      有什么不同?适合用于什么情景?
    6. 读写锁适用于什么情景?ReetrantReadWriteLock如何实现的?
    7. 线程之间如何通信?
    8. 保证线程安全的方法有哪些?
      • CAS,Lock,ThreadLocal
  4. 如何尽可能提高多线程并发性能?
    • 减少临界区范围
    • 使用读写锁
    • 使用CopyOnWrite
  5. ThreadLocal 的作用是什么?
* 用来隔离线程的数据,让线程的数据不在互相影响。
 * 不是用来线程共享数据
           
  1. 死锁问题产生的条件,如何避免死锁?
* 资源互斥
 * 持有资源并请求
 * 非剥夺
 * 循环等待
           

to be continued…