Tips

将一个知识点 分解为 xxx 是什么,xxx 有什么用,如何实现这个功能的(核心的工作流程),缺点是什么(以及为什么有这个缺点,缺点如何补救)。

举个例子, CMS 垃圾回收器回收时为什么有内存碎片 , 首先分解为 CMS 是什么,内存碎片是什么?CMS 垃圾回收器有什么用和 Serial ParNew Parallel 等比较,优势,CMS 是如何工作的,来实现尽可能降低响应时间的,为什么 CMS 有这个缺点,它是如何取舍的,如何补救这个缺点。

这些子问题都回答好,那么基本上这个问题就学的可以了。

这样可以检测你是否学好,而且,若是你都没法条理清晰地讲给自己,那怎么条理清晰地讲给面试官呢?

基础知识

原码、补码、反码

  • 原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是 8 位二进制:

[+1] 原 = 0000 0001

[-1] 原 = 1000 0001

  • 反码

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。

[+1] = [00000001] 原 = [00000001] 反

[-1] = [10000001] 原 = [11111110] 反

  • 补码

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后 + 1. (即在反码的基础上 + 1)

[+1] = [00000001] 原 = [00000001] 反 = [00000001] 补

[-1] = [10000001] 原 = [11111110] 反 = [11111111] 补

操作系统与环境

基础

Java如何使用多线程交替打印数组?

说一下进程和线程的区别?协程呢?

进程之间如何通信?说几种方法并且举一个例子

线程同步的方式

wait() 和 notify() 使用场景和作用
notify()
notify 方法是一个 native 方法,并且也是 final 的,不允许子类重写。

唤醒一个在此对象监视器上等待的线程 (监视器相当于就是锁的概念)。如果所有的线程都在此对象上等待,那么只会选择一个线程。选择是任意性的,并在对实现做出决定时发生。一个线程在对象监视器上等待可以调用 wait 方法。

直到当前线程放弃对象上的锁之后,被唤醒的线程才可以继续处理。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争。例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。

notify 方法只能被作为此对象监视器的所有者的线程来调用。一个线程要想成为对象监视器的所有者,可以使用以下 3 种方法:

执行对象的同步实例方法
使用 synchronized 内置锁
对于 Class 类型的对象,执行同步静态方法
一次只能有一个线程拥有对象的监视器。

wait()
wait 方法会让当前线程 (我们先叫做线程 T) 将其自身放置在对象的等待集中,并且放弃该对象上的所有同步要求。出于线程调度目的,线程 T 是不可用并处于休眠状态,直到发生以下四件事中的任意一件:

其他某个线程调用此对象的 notify 方法,并且线程 T 碰巧被任选为被唤醒的线程
其他某个线程调用此对象的 notifyAll 方法
其他某个线程调用 Thread.interrupt 方法中断线程 T
时间到了参数设置的超时时间。如果 timeout 参数为 0,则不会超时,会一直进行等待
所以可以理解 wait 方法相当于放弃了当前线程对对象监视器的所有者 (也就是说释放了对象的锁)。

之后,线程 T 会被等待集中被移除,并且重新进行线程调度。然后,该线程以常规方式与其他线程竞争,以获得在该对象上同步的权利;一旦获得对该对象的控制权,该对象上的所有其同步声明都将被恢复到以前的状态,这就是调用 wait 方法时的情况。然后,线程 T 从 wait 方法的调用中返回。所以,从 wait 方法返回时,该对象和线程 T 的同步状态与调用 wait 方法时的情况完全相同。
d
锁 Object 和锁 class 的区别

什么是死锁,死锁产生条件以及预防办法

阻塞、非阻塞、异步等

多线程与并发

谈谈 Java 堆和栈?

堆栈,栈溢出

解释一下信号量?

线程死锁如何调试?用什么工具来调试定位?

进程和线程的区别

什么是虚拟地址空间,如何完成虚拟地址空间到物理内存的映射

多线程同步的方法

线程同步有哪几种方式,解释一下 Volatile

实现多线程的三种方式,说说线程池

线程是不是开的越多越好,开多少合适,如何减少上下文切换开销,如何写个 shell 脚本获取上下文切换的开销?

ReentrantLock 和 Synchronized 区别

对 java 多线程有了解么?讲讲你对于多线程的学习和掌握

什么情况下需要用到多线程,多线程的好处、使用、原理、调度

有做过性能监测和调优相关的工作吗

分布式锁如何实现

除了加锁还有什么方法解决资源竞争

内存管理

说一下内存管理机制

内存泄露(如何产生,如何避免)

磁盘如何存储

静态资源分配和动态资源分配

进程和线程的区别

进程间通信的方式

线程同步机制

信号量的实现原理

IPC 方式有哪些, 用过哪些, 你知道的锁有哪些种, 有什么区别. (锁的种类没答出来)

说一说锁,原子变量怎么实现的

公平锁的实现

JVM

GC

类加载机制,说了双亲代理

虚拟机有几个类加载器,又讲了双亲委派

GC 判断和算法

JVM 能用外面的内存吗

JVM 内存分区、堆的分代

JVM 垃圾回收算法

线程池

CMS 垃圾回收过程

jvm 内存模型,1.6 1.7 1.8 哪里不同

类加载机制

gc 算法,可达性分析

考虑对于老年代怎么解决互联网应用中 gc 停顿问题,怎么解决内存碎片问题
锁,sync,lock(公平锁,非公平锁,实现) 读写锁,cas,aqs
jvm 调优,命令行工具 jstack jmap

jvm 工作原理

gc 算法,内存模型

为什么 jvm 调优经常会将 - Xms 和 - Xmx 参数设置成一样

CGLib 创建动态代理的原理

介绍一下 young gc、full gc、old gc、mix gc 的概念和区别,最好以具体垃圾收集器和收集算法为例进行介绍。

JVM 如何提供反射特性(Unsafe,动态字节码生成)

GC 策略

JDK 1.7 及以下版本,字节码存储在哪个区域

1.8 永久代的改变

JDK 自带的动态代理有什么限制

这里简要说明下 Java 中的绑定:绑定指的是把一个方法的调用与方法所在的类 (方法主体) 关联起来,对 java 来说,绑定分为静态绑定和动态绑定:

静态绑定:即前期绑定。在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。针对 java,简单的可以理解为程序编译期的绑定。java 当中的方法只有 final,static,private 和构造方法是前期绑定的。
动态绑定:即晚期绑定,也叫运行时绑定。在运行时根据具体对象的类型进行绑定。在 java 中,几乎所有的方法都是后期绑定的。
类加载器虽然只用于实现类的加载动作,但它在 Java 程序中起到的作用却远远不限于类的加载阶段。对于任意一个类,都需要由它的类加载器和这个类本身一同确定其在就 Java 虚拟机中的唯一性,也就是说,即使两个类来源于同一个 Class 文件,只要加载它们的类加载器不同,那这两个类就必定不相等。这里的 “相等” 包括了代表类的 Class 对象的 equals()、isAssignableFrom()、isInstance()等方法的返回结果,也包括了使用 instanceof 关键字对对象所属关系的判定结果。

Class.forName 的运行过程

问:G1 收集器是在哪个版本出来的?

答:不太清楚,就说是 1.5 之后。

问:那你知道内存 GC 的时候,要使用 Object 的什么方法吗?这个方法在什么时候使用?

答:finalize 方法,在进行第一次标记的时候,如果发现 GC Root 不能触及到时,就调用这个方法,如果该对象还没有复活,那么在下一次就进行回收。这个方法不管是否复活,都只调用一次。

最顶层的 ClassLoader 叫什么

能获得 Bootstrap ClassLoader 的引用吗

Synchronize 和 Lock 区别

集合框架,线程池,ThreadLocal,Cookie Session,RDB AOF 等

Java基础,集合类,List和Hashmap,还有concurrenthashmap对比,多线程

抽象类和接口

JVM内存模型,垃圾回收,问的很深,伊甸区复制到存活区究竟应该放到哪个地方,新建对象存在哪里

多线程线程池如何自己实现,栈内存多线程

动态代理和静态代理,正向代理和反向代理

类加载,有哪些 ClassLoader

JVM 回收算法和回收器,CMS 采用哪种回收算法,怎么解决内存碎片问题

说一下 G1 的策略

操作系统如何控制一个资源只能被一个进程访问,也就是锁是如何实现的?(这里我说能不能从 Java 说,面试官说,我需要底层原理,Java 应该解释不清楚)
项目的抢购模块如何解决超卖的问题?

项目里的 QPS 如何提高和优化的?

  1. GC 的原理
    答:没引用的对象就是可以回收的了,不定时选择回收与否, 略…

  2. 栈和堆内存的区别
    答:
    1、栈区(stack)—由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈
    2、堆区(heap)— 一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表
    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束后有系统释放
    4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放

5、程序代码区—存放函数体的二进制代码。

  1. 永生代是什么,为啥要有这个
    答:永久代用于存放静态文件,如 Java 类、方法等,引用关系比较稳定,一般不进行垃圾管理。但是,有些应用可能会动态生成 Class,在有些 JVM 的实现中会给永生代添加一些必要的回收算法。

问:那你怎么使用某种收集器呢?在哪个时候进行参数设置?

答:(翻白眼)当然是在 Java 运行的时候啊。(当时面试官不满意,追问我在具体哪个阶段)就说了具体的 Java 文件,字节码文件,Javac 命令和 Java 命令使用,在 Java 命令运行 Class 文件的时候进行参数设置。

Linux

Linux 下如何查看文件?在文件中如何搜索关键字?

用什么命令查看端口是否被占用?

Linux 常用指令,软连接硬链接区别说一下

Linux 进程间通信方式,管道的特点,消息队列的特点,什么时候使用这些通信方式,TB 级别数据传输使用何种进程间通信方式

Linux 查看打开的网络端口的命令是什么?

Linux 怎么抓包?

linux 命令行中如何使用管道?

java 线程池的几个参数的意义和实现机制。

JVM 调优实践,JVM 分区,栈堆空间,分配策略

Linux 用什么命令查看进程;

常用的linux指令

算法

常见排序算法的时间复杂度,空间复杂度

排序算法比较

从浏览器地址栏输入url到显示页面的步骤(以HTTP为例)

  1. 在浏览器地址栏输入URL
  2. 浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤
    1. 如果资源未缓存,发起新请求
    2. 如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证。
    3. 检验新鲜通常有两个HTTP头进行控制ExpiresCache-Control
      • HTTP1.0提供Expires,值为一个绝对时间表示缓存新鲜日期
      • HTTP1.1增加了Cache-Control: max-age=,值为以秒为单位的最大新鲜时间
  3. 浏览器解析URL获取协议,主机,端口,path
  4. 浏览器组装一个HTTP(GET)请求报文
  5. 浏览器获取主机ip地址,过程如下:
    1. 浏览器缓存
    2. 本机缓存
    3. hosts文件
    4. 路由器缓存
    5. ISP DNS缓存
    6. DNS递归查询(可能存在负载均衡导致每次IP不一样)
  6. 打开一个socket与目标IP地址,端口建立TCP链接,三次握手如下:
    1. 客户端发送一个TCP的SYN=1,Seq=X的包到服务器端口
    2. 服务器发回SYN=1, ACK=X+1, Seq=Y的响应包
    3. 客户端发送ACK=Y+1, Seq=Z
  7. TCP链接建立后发送HTTP请求
  8. 服务器接受请求并解析,将请求转发到服务程序,如虚拟主机使用HTTP Host头部判断请求的服务程序
  9. 服务器检查HTTP请求头是否包含缓存验证信息如果验证缓存新鲜,返回304等对应状态码
  10. 处理程序读取完整请求并准备HTTP响应,可能需要查询数据库等操作
  11. 服务器将响应报文通过TCP连接发送回浏览器
  12. 浏览器接收HTTP响应,然后根据情况选择关闭TCP连接或者保留重用,关闭TCP连接的四次握手如下
    1. 主动方发送Fin=1, Ack=Z, Seq= X报文
    2. 被动方发送ACK=X+1, Seq=Z报文
    3. 被动方发送Fin=1, ACK=X, Seq=Y报文
    4. 主动方发送ACK=Y, Seq=X报文
  13. 浏览器检查响应状态吗:是否为1XX,3XX, 4XX, 5XX,这些情况处理与2XX不同
  14. 如果资源可缓存,进行缓存
  15. 对响应进行解码(例如gzip压缩)
  16. 根据资源类型决定如何处理(假设资源为HTML文档)
  17. 解析HTML文档,构件DOM树,下载资源,构造CSSOM树,执行js脚本,这些操作没有严格的先后顺序,以下分别解释
  18. 构建DOM树
    1. Tokenizing:根据HTML规范将字符流解析为标记
    2. Lexing:词法分析将标记转换为对象并定义属性和规则
    3. DOM construction:根据HTML标记关系将对象组成DOM树
  19. 解析过程中遇到图片、样式表、js文件,启动下载
  20. 构建CSSOM树
    1. Tokenizing:字符流转换为标记流
    2. Node:根据标记创建节点
    3. CSSOM:节点创建CSSOM树
  21. 根据DOM树和CSSOM树构建渲染树:
    1. 从DOM树的根节点遍历所有可见节点,不可见节点包括:1)script,meta这样本身不可见的标签。2)被css隐藏的节点,如display: none
    2. 对每一个可见节点,找到恰当的CSSOM规则并应用
    3. 发布可视节点的内容和计算样式
  22. js解析如下
    1. 浏览器创建Document对象并解析HTML,将解析到的元素和文本节点添加到文档中,此时document.readystate为loading
    2. HTML解析器遇到没有async和defer的script时,将他们添加到文档中,然后执行行内或外部脚本。这些脚本会同步执行,并且在脚本下载和执行时解析器会暂停。这样就可以用document.write()把文本插入到输入流中。同步脚本经常简单定义函数和注册事件处理程序,他们可以遍历和操作script和他们之前的文档内容
    3. 当解析器遇到设置了async属性的script时,开始下载脚本并继续解析文档。脚本会在它下载完成后尽快执行,但是解析器不会停下来等它下载。异步脚本禁止使用document.write(),它们可以访问自己script和之前的文档元素
    4. 当文档完成解析,document.readState变成interactive
    5. 所有defer脚本会按照在文档出现的顺序执行,延迟脚本能访问完整文档树,禁止使用document.write()
    6. 浏览器在Document对象上触发DOMContentLoaded事件
    7. 此时文档完全解析完成,浏览器可能还在等待如图片等内容加载,等这些内容完成载入并且所有异步脚本完成载入和执行,document.readState变为complete,window触发load事件
  23. 显示页面(HTML解析过程中会逐步显示页面)

HTTP request报文结构是怎样的

rfc2616中进行了定义:

  1. 首行是Request-Line包括:请求方法请求URI协议版本CRLF
  2. 首行之后是若干行请求头,包括general-headerrequest-header或者entity-header,每个一行以CRLF结束
  3. 请求头和消息实体之间有一个CRLF分隔
  4. 根据实际请求需要可能包含一个消息实体
    一个请求报文例子如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET /Protocols/rfc2616/rfc2616-sec5.html HTTP/1.1
Host: www.w3.org
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Referer: https://www.google.com.hk/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: authorstyle=yes
If-None-Match: "2cc8-3e3073913b100"
If-Modified-Since: Wed, 01 Sep 2004 13:24:52 GMT
name=qiu&age=25

HTTP response报文结构是怎样的

rfc2616中进行了定义:

  1. 首行是状态行包括:HTTP版本,状态码,状态描述,后面跟一个CRLF
  2. 首行之后是若干行响应头,包括:通用头部,响应头部,实体头部
  3. 响应头部和响应实体之间用一个CRLF空行分隔
  4. 最后是一个可能的消息实体
    响应报文例子如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
HTTP/1.1 200 OK
Date: Tue, 08 Jul 2014 05:28:43 GMT
Server: Apache/2
Last-Modified: Wed, 01 Sep 2004 13:24:52 GMT
ETag: "40d7-3e3073913b100"
Accept-Ranges: bytes
Content-Length: 16599
Cache-Control: max-age=21600
Expires: Tue, 08 Jul 2014 11:28:43 GMT
P3P: policyref="http://www.w3.org/2001/05/P3P/p3p.xml"
Content-Type: text/html; charset=iso-8859-1
{"name": "qiu", "age": 25}