《面试复习指南》

面试题集合


Java基础

什么是面向对象
面向对象、面向过程

面向对象的三大基本特征和五大基本原则

→ 平台无关性
Java 如何实现的平台无关

JVM 还支持哪些语言(Kotlin、Groovy、JRuby、Jython、Scala)

→ 值传递
值传递、引用传递

为什么说 Java 中只有值传递

→ 封装、继承、多态
什么是多态、方法重写与重载

Java 的继承与实现

构造函数与默认构造函数

类变量、成员变量和局部变量

成员变量和方法作用域

基本数据类型
8种基本数据类型:整型、浮点型、布尔型、字符型

整型中 byte、short、int、long 的取值范围

什么是浮点型?什么是单精度和双精度?为什么不能用浮点型表示金额?

→ 自动拆装箱
什么是包装类型、什么是基本类型、什么是自动拆装箱

Integer 的缓存机制

→ String
字符串的不可变性

JDK 6 和 JDK 7 中 substring 的原理及区别、

replaceFirst、replaceAll、replace 区别、

String 对“+”的重载、字符串拼接的几种方式和区别

String.valueOf 和 Integer.toString 的区别、

switch 对 String 的支持

字符串池、常量池(运行时常量池、Class 常量池)、intern

→ 熟悉 Java 中各种关键字
transient、instanceof、final、static、volatile、synchronized、const 原理及用法

→ 集合类
常用集合类的使用、ArrayList 和 LinkedList 和 Vector 的区别 、SynchronizedList 和 Vector 的区别、HashMap、HashTable、ConcurrentHashMap 区别、

Set 和 List 区别?Set 如何保证元素不重复?

Java 8 中 stream 相关用法、apache 集合处理工具类的使用、不同版本的 JDK 中 HashMap 的实现的区别以及原因

Collection 和 Collections 区别

Arrays.asList 获得的 List 使用时需要注意什么

Enumeration 和 Iterator 区别

fail-fast 和 fail-safe

CopyOnWriteArrayList、ConcurrentSkipListMap

→ 枚举
枚举的用法、枚举的实现、枚举与单例、Enum 类

Java 枚举如何比较

switch 对枚举的支持

枚举的序列化如何实现

枚举的线程安全性问题

→ IO
字符流、字节流、输入流、输出流、

同步、异步、阻塞、非阻塞、Linux 5 种 IO 模型

BIO、NIO 和 AIO 的区别、三种 IO 的用法与原理、netty

→ 反射
反射与工厂模式、反射有什么用

Class 类、java.lang.reflect.*

→ 动态代理
静态代理、动态代理

动态代理和反射的关系

动态代理的几种实现方式

AOP

→ 序列化
什么是序列化与反序列化、为什么序列化、序列化底层原理、序列化与单例模式、protobuf、为什么说序列化并不安全

→ 注解
元注解、自定义注解、Java 中常用注解使用、注解与反射的结合

Spring 常用注解

→ JMS
什么是 Java 消息服务、JMS 消息传送模型

→ JMX
java.lang.management.、 javax.management.

→ 泛型
泛型与继承、类型擦除、泛型中 KTVE? object 等的含义、泛型各种用法

限定通配符和非限定通配符、上下界限定符 extends 和 super

List 和原始类型 List 之间的区别?

List<?> 和 List 之间的区别是什么?

→ 单元测试
junit、mock、mockito、内存数据库(h2)

→ 正则表达式
java.lang.util.regex.*

→ 常用的 Java 工具库
commons.lang、commons….、 guava-libraries、 netty

→ API & SPI
API、API 和 SPI 的关系和区别

如何定义 SPI、SPI 的实现原理

→ 异常
异常类型、正确处理异常、自定义异常

Error 和 Exception

异常链、try-with-resources

finally 和 return 的执行顺序

→ 时间处理
时区、冬令时和夏令时、时间戳、Java 中时间 API

格林威治时间、CET,UTC,GMT,CST 几种常见时间的含义和关系

SimpleDateFormat 的线程安全性问题

Java 8 中的时间处理

如何在东八区的计算机上获取美国时间

→ 编码方式
Unicode、有了 Unicode 为啥还需要 UTF-8

GBK、GB2312、GB18030 之间的区别

UTF8、UTF16、UTF32 区别

URL 编解码、Big Endian 和 Little Endian

如何解决乱码问题

→ 语法糖
Java 中语法糖原理、解语法糖

语法糖:switch 支持 String 与枚举、泛型、自动装箱与拆箱、方法变长参数、枚举、内部类、条件编译、 断言、数值字面量、for-each、try-with-resource、Lambda 表达式

03
阅读源代码

String、Integer、Long、Enum、

BigDecimal、ThreadLocal、ClassLoader & URLClassLoader、

ArrayList & LinkedList、

HashMap & LinkedHashMap & TreeMap & CouncurrentHashMap、HashSet & LinkedHashSet & TreeSet

java内存模型
多态(重载重写)
object方法
类访问权限
sleep、notify、wait 联系、区别
String、stringbuffer、stringbuilder 联系、区别、源码
Volatile 原理、源码、与syn区别
线程间通信方式
线程的各种状态
等等等等

集合框架
List

ArrayList
LinkedList
Vector
三者区别,联系,源码

Set

HashSet
LinkedHashSet
TreeSet
基于什么实现,内部数据结构,适用场景,源码

Map

HashMap
weakHashMao
LinkedHashMap
TreeMap
HashMap与hashtable的区别

内部实现原理、源码、适用场景

并发包
ConcurrentHashMap

原理、源码、与hashmap的区别

CopyOnWriteArrayList (set)

什么情况加锁、什么情况不加锁、适用场景

ArrayblockingQueue (Linked)

两者区别,take、put、offer、poll方法原理、源码
AtomicInteger (long boolean)

功能

CountDownLatch

功能、场景
CyclicBarrier

功能、场景
FutureTask (Callable)

源码、场景

ReentantLock

与syn的区别、好处、场景

Condition

与wait、notify的区别、好处

Semaphore

好处、场景

ReentrantReadWriteLock

读写分离的好处、适用场景、源码

Executors

线程池种类、各个作用、适用场景

ThreadPoolExecutor
重载方法的参数、各参数作用、源码

并发

04
Java 并发编程
→ 并发与并行
什么是并发、什么是并行

并发与并行的区别

→ 什么是线程,与进程的区别
线程的实现、线程的状态、优先级、线程调度、创建线程的多种方式、守护线程

线程与进程的区别

→ 线程池
自己设计线程池、submit() 和 execute()、线程池原理

为什么不允许使用 Executors 创建线程池

→ 线程安全
死锁、死锁如何排查、线程安全和内存模型的关系

→ 锁
CAS、乐观锁与悲观锁、数据库相关锁机制、分布式锁、偏向锁、轻量级锁、重量级锁、monitor、

锁优化、锁消除、锁粗化、自旋锁、可重入锁、阻塞锁、死锁

→ 死锁
什么是死锁

死锁如何解决

→ synchronized
synchronized 是如何实现的?

synchronized 和 lock 之间关系、不使用 synchronized 如何实现一个线程安全的单例

synchronized 和原子性、可见性和有序性之间的关系

→ volatile
happens-before、内存屏障、编译器指令重排和 CPU 指令重

volatile 的实现原理

volatile 和原子性、可见性和有序性之间的关系

有了 symchronized 为什么还需要 volatile

→ sleep 和 wait
→ wait 和 notify
→ notify 和 notifyAll
→ ThreadLocal
→ 写一个死锁的程序
→ 写代码来解决生产者消费者问题
→ 并方包
Thread、Runnable、Callable、ReentrantLock、ReentrantReadWriteLock、Atomic、Semaphore、CountDownLatch、ConcurrentHashMap、Executors

JVM

JVM五大区

每个区的存储、作用
JVM内存模型

类加载机制
双亲委派模型

垃圾收集器
常用gc算法
收集器种类、适用场景
fullGC、MinorGC触发条件

JVM优化
可视化工具使用
日志查询
各项参数设置
四种引用

→ JVM 内存结构
class 文件格式、运行时数据区:堆、栈、方法区、直接内存、运行时常量池、

堆和栈区别

Java 中的对象一定在堆上分配吗?

→ Java 内存模型
计算机内存模型、缓存一致性、MESI 协议

可见性、原子性、顺序性、happens-before、

内存屏障、synchronized、volatile、final、锁

→ 垃圾回收
GC 算法:标记清除、引用计数、复制、标记压缩、分代回收、增量式回收

GC 参数、对象存活的判定、垃圾收集器(CMS、G1、ZGC、Epsilon)

→ JVM 参数及调优
-Xmx、-Xmn、-Xms、Xss、-XX:SurvivorRatio、

-XX:PermSize、-XX:MaxPermSize、-XX:MaxTenuringThreshold

→ Java 对象模型
oop-klass、对象头

→ HotSpot
即时编译器、编译优化

→ 虚拟机性能监控与故障处理工具
jps, jstack, jmap, jstat, jconsole, jinfo, jhat, javap, btrace, TProfiler

Arthas

02
类加载机制

classLoader、类加载过程、双亲委派(破坏双亲委派)、模块化(jboss modules、osgi、jigsaw)

03
编译与反编译

什么是编译(前端编译、后端编译)、什么是反编译

JIT、JIT 优化(逃逸分析、栈上分配、标量替换、锁优化)

编译工具:javac

反编译工具:javap 、jad 、CRF

IO流

BIO

字节流:类型、适用场景
字符流:类型、适用场景

NIO
类型、适用场景
三大组件的联系、使用
内存情况

web

web
Tomcat

结构、流程、源码
Servlet

生命周期
三种实现方式

Spring

→ Servlet

生命周期

线程安全问题

filter 和 listener

web.xml 中常用配置及作用

→ Hibernate
什么是 OR Mapping

Hibernate 的懒加载
Hibernate 的缓存机制

Hibernate / Ibatis / MyBatis 之间的区别

→ Spring
Bean 的初始化
AOP 原理
实现 Spring 的IOC
Spring 四种依赖注入方式
→ Spring MVC
什么是 MVC

Spring mvc 与 Struts mvc 的区别

→ Spring Boot
Spring Boot 2.0、起步依赖、自动配置、

Spring Boot 的 starter 原理,自己实现一个 starter

→ Spring Security
→ Spring Cloud
服务发现与注册:Eureka、Zookeeper、Consul

负载均衡:Feign、Spring Cloud Loadbalance

服务配置:Spring Cloud Config

服务限流与熔断:Hystrix

服务链路追踪:Dapper

服务网关、安全、消息
springMVC
使用
请求流程

IOC/AOP 原理、源码、联系
两种动态代理实现

mybatis
使用

#、$区别
一级、二级缓存

设计模式

单例模式
工厂模式
观察者模式
适配器模式
模仿方法模式
策略模式
责任链模式
装饰者模式

常用的八种掌握就行,原理,使用
单例、工厂、观察者重点
设计模式
设计模式的六大原则:

开闭原则(Open Close Principle)、里氏代换原则(Liskov Substitution Principle)、依赖倒转原则(Dependence Inversion Principle)

接口隔离原则(Interface Segregation Principle)、迪米特法则(最少知道原则)(Demeter Principle)、合成复用原则(Composite Reuse Principle)

→ 了解 23 种设计模式

创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。

结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter 模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。

→ 会使用常用设计模式
单例的七种写法:懒汉——线程不安全、懒汉——线程安全、饿汉、饿汉——变种、静态内部类、枚举、双重校验锁

工厂模式、适配器模式、策略模式、模板方法模式、观察者模式、外观模式、代理模式等必会

数据结构

二叉树

平衡二叉树
二叉查找树
红黑树
完全二叉树
满二叉树

概念、适用场景、时间复杂度、好处坏处
B树

B-Tree
B+Tree

两者的联系、区别、适用场景

算法

直接插入排序
二分插入排序
希尔插入排序
冒泡排序
快排
选择排序
堆排序
归并排序

各种排序的思想
实现复杂度
稳定性如何
可以手写

网络

TCP

三次握手、四次挥手、各种状态、状态改变
和UDP的区别

网络编程知识
→ tcp、udp、http、https 等常用协议

三次握手与四次关闭、流量控制和拥塞控制、OSI 七层模型、tcp 粘包与拆包

→ http/1.0 http/1.1 http/2 之前的区别
http 中 get 和 post 区别

常见的 web 请求返回的状态码

404、302、301、500分别代表什么

→ http/3
→ Java RMI,Socket,HttpClient
→ cookie 与 session
cookie 被禁用,如何实现 session

→ 用 Java 写一个简单的静态文件的 HTTP 服务器
→ 了解 nginx 和 apache 服务器的特性并搭建一个对应的服务器
→ 用 Java 实现 FTP、SMTP 协议
→ 进程间通讯的方式
→ 什么是 CDN?如果实现?
→ DNS
什么是 DNS 、记录类型: A 记录、CNAME 记录、AAAA 记录等
域名解析、根域名服务器

DNS 污染、DNS 劫持、公共 DNS:114 DNS、Google DNS、OpenDNS

→ 反向代理
正向代理、反向代理

反向代理服务器

IO模型

同步、异步、阻塞、非阻塞概念
模型种类、各自特点、适用场景
如何使用

Linux基础

常用命令
管道符
查看日志相关命令
CPU使用命令

01
Java 底层知识
→ 字节码、class 文件格式
→ CPU 缓存,L1,L2,L3 和伪共享
→ 尾递归
→ 位运算
用位运算实现加、减、乘、除、取余

02

→ 不用 synchronized 和 lock,实现线程安全的单例模式
→ 实现 AOP
→ 实现 IOC
→ nio 和 reactor 设计模式

01
新技术

→ Java 8

lambda 表达式、Stream API、时间 API

→ Java 9
Jigsaw、Jshell、Reactive Streams

→ Java 10
局部变量类型推断、G1 的并行 Full GC、ThreadLocal 握手机制

→ Java 11
ZGC、Epsilon、增强 var

→ Spring 5
响应式编程

→ Spring Boot 2.0
→ HTTP/2
→ HTTP/3

02
性能优化

使用单例、使用 Future 模式、使用线程池

选择就绪、减少上下文切换、减少锁粒度、数据压缩、结果缓存

03
线上问题分析

→ dump 获取

线程 Dump、内存 Dump、gc 情况

→ dump 分析
分析死锁、分析内存泄露

→ dump 分析及获取工具
jstack、jstat、jmap、jhat、Arthas

→ 自己编写各种 outofmemory,stackoverflow 程序
HeapOutOfMemory、 Young OutOfMemory、

MethodArea OutOfMemory、ConstantPool OutOfMemory、

DirectMemory OutOfMemory、Stack OutOfMemory Stack OverFlow

→ Arthas
jvm 相关、class/classloader 相关、monitor/watch/trace 相关、

options、管道、后台异步任务

文档:https://alibaba.github.io/arthas/advanced-use.html

→ 常见问题解决思路
内存溢出、线程死锁、类加载冲突

→ 使用工具尝试解决以下问题,并写下总结
当一个 Java 程序响应很慢时如何查找问题

当一个 Java 程序频繁 FullGC 时如何解决问题

如何查看垃圾回收日志

当一个 Java 应用发生 OutOfMemory 时该如何解决

如何判断是否出现死锁

如何判断是否存在内存泄露

使用 Arthas 快速排查 Spring Boot 应用404/401问题

使用 Arthas 排查线上应用日志打满问题

利用 Arthas 排查 Spring Boot 应用 NoSuchMethodError

04
编译原理知识

→ 编译与反编译

→ Java 代码的编译与反编译
→ Java 的反编译工具
javap 、jad 、CRF

→ 即时编译器
→ 编译过程
词法分析,语法分析(LL 算法,递归下降算法,LR 算法)
语义分析,运行时环境,中间代码,代码生成,代码优化

05
操作系统知识

→ Linux 的常用命令
→ 进程间通信
→ 进程同步
生产者消费者问题、哲学家就餐问题、读者写者问题

→ 缓冲区溢出
→ 分段和分页
→ 虚拟内存与主存
→ 虚拟内存管理
→ 换页算法

06

07
数据结构与算法知识

→ 简单的数据结构

栈、队列、链表、数组、哈希表、

栈和队列的相同和不同之处

栈通常采用的两种存储结构

→ 树
二叉树、字典树、平衡树、排序树、

B 树、B+ 树、R 树、多路树、红黑树

→ 堆
大根堆、小根堆

→ 图
有向图、无向图、拓扑

→ 排序算法
稳定的排序:冒泡排序、插入排序、鸡尾酒排序、桶排序、计数排序、归并排序、原地归并排序、二叉排序树排序、鸽巢排序、基数排序、侏儒排序、图书馆排序、块排序

不稳定的排序:选择排序、希尔排序、Clover 排序算法、梳排序、堆排序、平滑排序、快速排序、内省排序、耐心排序

各种排序算法和时间复杂度

→ 两个栈实现队列,和两个队列实现栈
→ 深度优先和广度优先搜索
→ 全排列、贪心算法、KMP 算法、hash 算法
→ 海量数据处理
分治,hash 映射,堆排序,双层桶划分,Bloom Filter,bitmap,数据库索引,mapreduce 等。

08
大数据知识

→ Zookeeper

基本概念、常见用法

→ Solr,Lucene,ElasticSearch
在 linux 上部署 solr,solrcloud,新增、删除、查询索引

→ Storm,流式计算,了解 Spark,S4
在 linux 上部署 storm,用 zookeeper 做协调,运行 storm hello world,local 和 remote 模式运行调试 storm topology。

→ Hadoop,离线计算
HDFS、MapReduce

→ 分布式日志收集 flume,kafka,logstash
→ 数据挖掘,mahout

09
网络安全知识

→ XSS

XSS 的防御

→ CSRF
→ 注入攻击
SQL 注入、XML 注入、CRLF 注入

→ 文件上传漏洞
→ 加密与解密
对称加密、非对称加密、哈希算法、加盐哈希算法

MD5,SHA1、DES、AES、RSA、DSA

彩虹表

→ DDOS攻击
DOS 攻击、DDOS 攻击

memcached 为什么可以导致 DDos 攻击、什么是反射型 DDoS

如何通过 Hash 碰撞进行 DOS 攻击

→ SSL、TLS,HTTPS
→ 用 openssl 签一个证书部署到 apache 或 nginx

5

架构篇

01
分布式

数据一致性、服务治理、服务降级

→ 分布式事务
2PC、3PC、CAP、BASE、 可靠消息最终一致性、最大努力通知、TCC

→ Dubbo
服务注册、服务发现,服务治理

http://dubbo.apache.org/zh-cn/

→ 分布式数据库
怎样打造一个分布式数据库、什么时候需要分布式数据库、

mycat、otter、HBase

→ 分布式文件系统
mfs、fastdfs

→ 分布式缓存
缓存一致性、缓存命中率、缓存冗余

→ 限流降级
Hystrix、Sentinal

→ 算法
共识算法、Raft 协议、Paxos 算法与 Raft 算法、

拜占庭问题与算法、2PC、3PC

02
微服务

SOA、康威定律

→ ServiceMesh
sidecar

→ Docker & Kubernets
→ Spring Boot
→ Spring Cloud

03
高并发

→ 分库分表

→ CDN 技术
→ 消息队列
ActiveMQ

04
监控

→ 监控什么

CPU、内存、磁盘 I/O、网络 I/O 等

→ 监控手段
进程监控、语义监控、机器资源监控、数据波动

→ 监控数据采集
日志、埋点

→ Dapper

05
负载均衡

tomcat 负载均衡、Nginx 负载均衡

四层负载均衡、七层负载均衡

06
DNS

DNS 原理、DNS 的设计

07
CDN
数据一致性

6

扩展篇

01
云计算

IaaS、SaaS、PaaS、虚拟化技术、openstack、Serverlsess

02
搜索引擎

Solr、Lucene、Nutch、Elasticsearch

03
权限管理
Shiro

04
区块链

哈希算法、Merkle 树、公钥密码算法、共识算法、

Raft 协议、Paxos 算法与 Raft 算法、拜占庭问题与算法、消息认证码与数字签名

→ 比特币
挖矿、共识机制、闪电网络、侧链、热点问题、分叉

→ 以太坊
→ 超级账本

05
人工智能

数学基础、机器学习、人工神经网络、深度学习、应用场景。

→ 常用框架
TensorFlow、DeepLearning4J

06
loT

07
量子计算

08
AR & VR

09
其他语言

Groovy、Python、Go、NodeJs、Swift、Rust

7

推荐书籍

《深入理解 Java 虚拟机》
《Effective Java》
《深入分析 Java Web 技术内幕》
《大型网站技术架构》
《代码整洁之道》
《架构整洁之道》
《Head First 设计模式》
《maven 实战》
《区块链原理、设计与应用》
《Java 并发编程实战》
《鸟哥的 Linux 私房菜》
《从Paxos 到 Zookeeper》
《架构即未来》

基于BIO实现的Server端,当建立了100个连接时,会有多少个线程?如果基于NIO,又会是多少个线程? 为什么?

通常来说基于NIO实现的Server端,会用多少个线程去处理IO事件,为什么?

一个典型的客户端集群->LB->服务端集群这样的结构中,如客户端采用连接池,长连接的方式,这种设计你觉得可能会出现什么问题?如果客户端采用的是单个长连接的方式呢?如果有问题,你觉得应该怎么解决?

cglib和Java的动态代理相比,具体有什么不同?

在基于Netty实现FrameDecoder时,下面两种代码的表现会有什么不同?

第一种

private void callDecode(…) {

  List<Object> results = new ArrayList<Object>();

  while (cumulation.readable()) {

        int oldReaderIndex = cumulation.readerIndex();

        Object frame = decode(context, channel, cumulation);

        if (frame == null) {

             if (oldReaderIndex == cumulation.readerIndex())

                   break;

             else

                  continue;

       }

      else if (oldReaderIndex == cumulation.readerIndex()) {

             throw new IllegalStateException( ".....");

       }

       results.add(frame);

}

if(results.size() > 0)

    fireMessageReceived(context, remoteAddress, results);

}

第二种

private void callDecode(…) {

int oldReaderIndex = cumulation.readerIndex();

Object frame = decode(context, channel, cumulation);

if (frame != null)

       fireMessageReceived(context, remoteAddress, frame);

}

用Executors.newCachedThreadPool创建的线程池,在运行的过程中有可能产生的风险是?

new ThreadPoolExecutor(10,100,10,TimeUnit.MILLISECONDS,new LinkedBlockingQueue(10));一个这样创建的线程池,当已经有10个任务在运行时,第11个任务提交到此线程池执行的时候会发生什么,为什么?

实现一个自定义的ThreadFactory的作用通常是?

除了用Object.wait和Object.notifyAll来实现线程间的交互外,你还会常用哪些来实现?

为什么ConcurrentHashMap可以在高并发的情况下比HashMap更为高效?

AtomicInteger、AtomicBoolean这些类之所以在高并发时高效,共同的原因是?

请合理的使用Queue来实现一个高并发的生产/消费的场景,给些核心的代码片段。

请实现让10个任务同时并发启动,给些代码片段。

在Java程序运行阶段,可以用什么命令行工具来查看当前Java程序的一些启动参数值,例如Heap Size等。

用什么命令行工具可以查看运行的Java程序的GC状况,请具体写出命令行格式。

用什么工具,可以在Java程序运行的情况下跟踪某个方法的执行时间,请求参数信息等,并请解释下工具实现的原理。

当一个Java程序接收请求,很长时间都没响应的话,通常你会怎么去排查这种问题?

Java进程突然消失了,你会怎么去排查这种问题?

以下这段代码思路,你觉得在运行时可能会产生的风险是,应该如何改进?

public List getUsers(String[] userIds){

 // 从数据库查找符合userIds的user记录

//  将返回的记录组装为User对象,放入List并返回

}

以下两种代码,在运行时有什么不同?为什么?

第一种

private static final boolean isLoggerDebugEnabled = log.isDebugEnabled();

public void xx(User user){

if(isLoggerDebugEnabled){

     log.debug("enter xx method, user id is: " + user.getId());

}

}

第二种

public void xx(User user){

log.debug("enter xx method, user id is: " + user.getId());

}

Java程序为什么通常在刚启动的时候会执行的比较慢,而处理了一些请求后会变快,AOT能带来什么帮助?

Parallel GC、CMS GC、ZGC、Azul Pauseless GC最主要的不同是?背后的原理也请简单描述下?

请写一段程序,让其运行时的表现为触发5次ygc,然后3次fgc,然后3次ygc,然后1次fgc,请给出代码以及启动参数。

Go的Coroutine和Java的线程机制最主要的不同是?如果Java语言要透明的实现Coroutine,你觉得主要的难点是?

1、MySQL的复制原理以及流程

基本原理流程,3个线程以及之间的关联;

2、MySQL中myisam与innodb的区别,至少5点

(1)、问5点不同;

(2)、innodb引擎的4大特性

(3)、2者selectcount()哪个更快,为什么

3、MySQL中varchar与char的区别以及varchar(50)中的50代表的涵义

(1)、varchar与char的区别

(2)、varchar(50)中50的涵义

(3)、int(20)中20的涵义

(4)、mysql为什么这么设计

4、问了innodb的事务与日志的实现方式

(1)、有多少种日志;

(2)、事物的4种隔离级别

(3)、事务是如何通过日志来实现的,说得越深入越好。

5、问了MySQL binlog的几种日志录入格式以及区别

(1)、binlog的日志格式的种类和分别

(2)、适用场景;

(3)、结合第一个问题,每一种日志格式在复制中的优劣。

6、问了下MySQL数据库cpu飙升到500%的话他怎么处理?

(1)、没有经验的,可以不问;

(2)、有经验的,问他们的处理思路。

7、sql优化

(1)、explain出来的各种item的意义;

(2)、profile的意义以及使用场景;

8、备份计划,mysqldump以及xtranbackup的实现原理

(1)、备份计划;

(2)、备份恢复时间;

(3)、xtrabackup实现原理

9、mysqldump中备份出来的sql,如果我想sql文件中,一行只有一个insert….value()的话,怎么办?如果备份需要带上master的复制点信息怎么办?

10、500台db,在最快时间之内重启

.

11、innodb的读写参数优化

(1)、读取参数

(2)、写入参数;

(3)、与IO相关的参数;

(4)、缓存参数以及缓存的适用场景。

12、你是如何监控你们的数据库的?你们的慢日志都是怎么查询的?

.

13、你是否做过主从一致性校验,如果有,怎么做的,如果没有,你打算怎么做?

14、你们数据库是否支持emoji表情,如果不支持,如何操作?

.

15、你是如何维护数据库的数据字典的?

16、你们是否有开发规范,如果有,如何执行的

17、表中有大字段X(例如:text类型),且字段X不会经常更新,以读为为主,请问

(1)、您是选择拆成子表,还是继续放一起;

(2)、写出您这样选择的理由。

18、MySQL中InnoDB引擎的行锁是通过加在什么上完成(或称实现)的?为什么是这样子的?

.

19、如何从mysqldump产生的全库备份中只恢复某一个库、某一张表?

开放性问题:据说是腾讯的

一个6亿的表a,一个3亿的表b,通过外间tid关联,你如何最快的查询出满足条件的第50000到第50200中的这200条数据记录。

Part4:答案

1、MySQL的复制原理以及流程

基本原理流程,3个线程以及之间的关联;

  1. 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中;

  2. 从:io线程——在使用start slave 之后,负责从master上拉取 binlog 内容,放进 自己的relay log中;

  3. 从:sql执行线程——执行relay log中的语句;

2、MySQL中myisam与innodb的区别,至少5点

(1)、问5点不同;

1>.InnoDB支持事物,而MyISAM不支持事物

2>.InnoDB支持行级锁,而MyISAM支持表级锁

3>.InnoDB支持MVCC, 而MyISAM不支持

4>.InnoDB支持外键,而MyISAM不支持

5>.InnoDB不支持全文索引,而MyISAM支持。

(2)、innodb引擎的4大特性

插入缓冲(insert buffer),二次写(double write),自适应哈希索引(ahi),预读(read ahead)

(3)、2者selectcount()哪个更快,为什么

myisam更快,因为myisam内部维护了一个计数器,可以直接调取。

3、MySQL中varchar与char的区别以及varchar(50)中的50代表的涵义
(1)、varchar与char的区别
char是一种固定长度的类型,varchar则是一种可变长度的类型
(2)、varchar(50)中50的涵义
最多存放50个字符,varchar(50)和(200)存储hello所占空间一样,但后者在排序时会消耗更多内存,因为order by col采用fixed_length计算col长度(memory引擎也一样)
(3)、int(20)中20的涵义
是指显示字符的长度
但要加参数的,最大为255,比如它是记录行数的id,插入10笔资料,它就显示00000000001 ~~~00000000010,当字符的位数超过11,它也只显示11位,如果你没有加那个让它未满11位就前面加0的参数,它不会在前面加0
20表示最大显示宽度为20,但仍占4字节存储,存储范围不变;
(4)、mysql为什么这么设计
对大多数应用没有意义,只是规定一些工具用来显示字符的个数;int(1)和int(20)存储和计算均一样;
4、问了innodb的事务与日志的实现方式
(1)、有多少种日志;
错误日志:记录出错信息,也记录一些警告信息或者正确的信息。
查询日志:记录所有对数据库请求的信息,不论这些请求是否得到了正确的执行。
慢查询日志:设置一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询的日志文件中。
二进制日志:记录对数据库执行更改的所有操作。
中继日志:
事务日志:
(2)、事物的4种隔离级别
隔离级别
读未提交(RU)
读已提交(RC)
可重复读(RR)
串行
(3)、事务是如何通过日志来实现的,说得越深入越好。
事务日志是通过redo和innodb的存储引擎日志缓冲(Innodb log buffer)来实现的,当开始一个事务的时候,会记录该事务的lsn(log sequence number)号; 当事务执行时,会往InnoDB存储引擎的日志
的日志缓存里面插入事务日志;当事务提交时,必须将存储引擎的日志缓冲写入磁盘(通过innodb_flush_log_at_trx_commit来控制),也就是写数据前,需要先写日志。这种方式称为“预写日志方式”
5、问了MySQL binlog的几种日志录入格式以及区别
(1)、binlog的日志格式的种类和分别
(2)、适用场景;
(3)、结合第一个问题,每一种日志格式在复制中的优劣。
Statement:每一条会修改数据的sql都会记录在binlog中。
优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。(相比row能节约多少性能 与日志量,这个取决于应用的SQL情况,正常同一条记录修改或者插入row格式所产生的日志量还小于Statement产生的日志量,但是考虑到如果带条 件的update操作,以及整表删除,alter表等操作,ROW格式会产生大量日志,因此在考虑是否使用ROW格式日志时应该跟据应用的实际情况,其所 产生的日志量会增加多少,以及带来的IO性能问题。)
缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的 一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有很多相关问题(如sleep()函数, last_insert_id(),以及user-defined functions(udf)会出现问题).
使用以下函数的语句也无法被复制:

  • LOAD_FILE()
  • UUID()
  • USER()
  • FOUND_ROWS()
  • SYSDATE() (除非启动时启用了 –sysdate-is-now 选项)
    同时在INSERT …SELECT 会产生比 RBR 更多的行级锁
    2.Row:不记录sql语句上下文相关信息,仅保存哪条记录被修改。
    优点: binlog中可以不记录执行的sql语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。所以rowlevel的日志内容会非常清楚的记录下 每一行数据修改的细节。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题
    缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比 如一条update语句,修改多条记录,则binlog中每一条修改都会有记录,这样造成binlog日志量会很大,特别是当执行alter table之类的语句的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中。
    3.Mixedlevel: 是以上两种level的混合使用,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则 采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择 一种.新版本的MySQL中队row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录。至于update或者delete等修改数据的语句,还是会记录所有行的 变更。
    6、问了下MySQL数据库cpu飙升到500%的话他怎么处理?
    (1)、没有经验的,可以不问;
    (2)、有经验的,问他们的处理思路。
    列出所有进程 show processlist 观察所有进程 多秒没有状态变化的(干掉)
    查看超时日志或者错误日志 (做了几年开发,一般会是查询以及大批量的插入会导致cpu与i/o上涨,,,,当然不排除网络状态突然断了,,导致一个请求服务器只接受到一半,比如where子句或分页子句没有发送,,当然的一次被坑经历)
    7、sql优化
    (1)、explain出来的各种item的意义;
    select_type
    表示查询中每个select子句的类型
    type
    表示MySQL在表中找到所需行的方式,又称“访问类型”
    possible_keys
    指出MySQL能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
    key
    显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL
    key_len
    表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度
    ref
    表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
    Extra
    包含不适合在其他列中显示但十分重要的额外信息
    (2)、profile的意义以及使用场景;
    查询到 SQL 会执行多少时间, 并看出 CPU/Memory 使用量, 执行过程中 Systemlock, Table lock 花多少时间等等
    8、备份计划,mysqldump以及xtranbackup的实现原理
    (1)、备份计划;
    这里每个公司都不一样,您别说那种1小时1全备什么的就行
    (2)、备份恢复时间;
    这里跟机器,尤其是硬盘的速率有关系,以下列举几个仅供参考
    20G的2分钟(mysqldump)
    80G的30分钟(mysqldump)
    111G的30分钟(mysqldump)
    288G的3小时(xtra)
    3T的4小时(xtra)
    逻辑导入时间一般是备份时间的5倍以上
    (3)、xtrabackup实现原理
    在InnoDB内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改。当InnoDB启动时,InnoDB会检查数据文件和事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。
    9、mysqldump中备份出来的sql,如果我想sql文件中,一行只有一个insert….value()的话,怎么办?如果备份需要带上master的复制点信息怎么办?
    –skip-extended-insert
    [root@helei-zhuanshu ~]# mysqldump -uroot -p helei –skip-extended-insert
    Enter password:
    KEY idx_c1 (c1),
    KEY idx_c2 (c2)
    ) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=latin1;

    /!40101 SET character_set_client = @saved_cs_client /;

    – Dumping data for table helei

    LOCK TABLES helei WRITE;
    /!40000 ALTER TABLE helei DISABLE KEYS /;
    INSERT INTO helei VALUES (1,32,37,38,’2016-10-18 06:19:24’,’susususususususususususu’);
    INSERT INTO helei VALUES (2,37,46,21,’2016-10-18 06:19:24’,’susususususu’);
    INSERT INTO helei VALUES (3,21,5,14,’2016-10-18 06:19:24’,’susu’);
    10、500台db,在最快时间之内重启
    puppet,dsh
    11、innodb的读写参数优化
    (1)、读取参数
    global buffer pool以及 local buffer;

(2)、写入参数;
innodb_flush_log_at_trx_commit
innodb_buffer_pool_size

(3)、与IO相关的参数;
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_thread_concurrency = 0

(4)、缓存参数以及缓存的适用场景。
query cache/query_cache_type
并不是所有表都适合使用query cache。造成query cache失效的原因主要是相应的table发生了变更

第一个:读操作多的话看看比例,简单来说,如果是用户清单表,或者说是数据比例比较固定,比如说商品列表,是可以打开的,前提是这些库比较集中,数据库中的实务比较小。
第二个:我们“行骗”的时候,比如说我们竞标的时候压测,把query cache打开,还是能收到qps激增的效果,当然前提示前端的连接池什么的都配置一样。大部分情况下如果写入的居多,访问量并不多,那么就不要打开,例如社交网站的,10%的人产生内容,其余的90%都在消费,打开还是效果很好的,但是你如果是qq消息,或者聊天,那就很要命。
第三个:小网站或者没有高并发的无所谓,高并发下,会看到 很多 qcache 锁 等待,所以一般高并发下,不建议打开query cache

12、你是如何监控你们的数据库的?你们的慢日志都是怎么查询的?
监控的工具有很多,例如zabbix,lepus,我这里用的是lepus

13、你是否做过主从一致性校验,如果有,怎么做的,如果没有,你打算怎么做?
主从一致性校验有多种工具 例如checksum、mysqldiff、pt-table-checksum等

14、你们数据库是否支持emoji表情,如果不支持,如何操作?
如果是utf8字符集的话,需要升级至utf8_mb4方可支持

15、你是如何维护数据库的数据字典的?
这个大家维护的方法都不同,我一般是直接在生产库进行注释,利用工具导出成excel方便流通。

16、你们是否有开发规范,如果有,如何执行的
有,开发规范网上有很多了,可以自己看看总结下

17、表中有大字段X(例如:text类型),且字段X不会经常更新,以读为为主,请问
(1)、您是选择拆成子表,还是继续放一起;
(2)、写出您这样选择的理由。
答:拆带来的问题:连接消耗 + 存储拆分空间;不拆可能带来的问题:查询性能;
如果能容忍拆分带来的空间问题,拆的话最好和经常要查询的表的主键在物理结构上放置在一起(分区) 顺序IO,减少连接消耗,最后这是一个文本列再加上一个全文索引来尽量抵消连接消耗
如果能容忍不拆分带来的查询性能损失的话:上面的方案在某个极致条件下肯定会出现问题,那么不拆就是最好的选择

18、MySQL中InnoDB引擎的行锁是通过加在什么上完成(或称实现)的?为什么是这样子的?
答:InnoDB是基于索引来完成行锁
例: select * from tab_with_index where id = 1 for update;
for update 可以根据条件来完成行锁锁定,并且 id 是有索引键的列,
如果 id 不是索引键那么InnoDB将完成表锁,,并发将无从谈起

.

19、如何从mysqldump产生的全库备份中只恢复某一个库、某一张表?
答案见:http://suifu.blog.51cto.com/9167728/1830651

开放性问题:据说是腾讯的
一个6亿的表a,一个3亿的表b,通过外间tid关联,你如何最快的查询出满足条件的第50000到第50200中的这200条数据记录。
1、如果A表TID是自增长,并且是连续的,B表的ID为索引
select * from a,b where a.tid = b.id and a.tid>500000 limit 200;

2、如果A表的TID不是连续的,那么就需要使用覆盖索引.TID要么是主键,要么是辅助索引,B表ID也需要有索引。
select * from b , (select tid from a limit 50000,200) a where b.id = a .tid;

数据库

数据库
三范式

主从复制

原理、实现

读写分离

原理、实现

事务

类型
使用
可能引起的问题

存储引擎

InnoDB
MyISAM
区别、联系、锁机制、适用场景

索引

类型
使用
什么样的字段适合做索引
SQL优化

1、一张表里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把mysql重启,再insert一条记录,这条记录的ID是18还是15 ?
2、mysql的技术特点是什么?
3、Heap表是什么?
4、mysql服务器默认端口是什么?
5、与Oracle相比,mysql有什么优势?
6、如何区分FLOAT和DOUBLE?
7、区分CHAR_LENGTH和LENGTH?
8、请简洁描述mysql中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别?
9、在mysql中ENUM的用法是什么?
10、如何定义REGEXP?
11、CHAR和VARCHAR的区别?
12、列的字符串类型可以是什么?
13、如何获取当前的mysql版本?
14、mysql中使用什么存储引擎?
15、mysql驱动程序是什么?
16、TIMESTAMP在UPDATE CURRENT_TIMESTAMP数据类型上做什么?
17、主键和候选键有什么区别?
18、如何使用Unix shell登录mysql?
19、 myisamchk是用来做什么的?
20、mysql数据库服务器性能分析的方法命令有哪些?
21、如何控制HEAP表的最大尺寸?
22、MyISAM Static和MyISAM Dynamic有什么区别?
23、federated表是什么?
24、如果一个表有一列定义为TIMESTAMP,将发生什么?
25、列设置为AUTO INCREMENT时,如果在表中达到最大值,会发生什么情况?
26、怎样才能找出最后一次插入时分配了哪个自动增量?
27、你怎么看到为表格定义的所有索引?
28、LIKE声明中的%和_是什么意思?
29、如何在Unix和mysql时间戳之间进行转换?
30、列对比运算符是什么?
31、我们如何得到受查询影响的行数?
32、mysql查询是否区分大小写?
33、LIKE和REGEXP操作有什么区别?
34、BLOB和TEXT有什么区别?
35、mysql_fetch_array和mysql_fetch_object的区别是什么?
36、我们如何在mysql中运行批处理模式?
37、MyISAM表格将在哪里存储,并且还提供其存储格式?
38、mysql中有哪些不同的表格?
39、ISAM是什么?
40、InnoDB是什么?
41、mysql如何优化DISTINCT?
42、如何输入字符为十六进制数字?
43、如何显示前50行?
44、可以使用多少列创建索引?
45、NOW()和CURRENT_DATE()有什么区别?
46、什么样的对象可以使用CREATE语句创建?
47、mysql表中允许有多少个TRIGGERS?
48、什么是非标准字符串类型?
49、什么是通用SQL函数?
50、解释访问控制列表
51、mysql支持事务吗?
52、mysql里记录货币用什么字段类型好?
53、mysql数据表在什么情况下容易损坏?
54、mysql有关权限的表都有哪几个?
55、mysql中有哪几种锁

数据库知识

→ MySQL 执行引擎

→ MySQL 执行计划
如何查看执行计划,如何根据执行计划进行 SQL 优化

→ 索引
Hash 索引、B 树索引(B+树、和B树、R树)

普通索引、唯一索引

覆盖索引、最左前缀原则、索引下推

→ SQL 优化
→ 数据库事务和隔离级别
事务的隔离级别、事务能不能实现锁的功能

→ 数据库锁
行锁、表锁、使用数据库锁实现乐观锁、

→ 连接
内连接,左连接,右连接

→ 数据库主备搭建
→ binlog
→ redolog
→ 内存数据库
h2

→ 分库分表
→ 读写分离
→ 常用的 NoSql 数据库
redis、memcached

→ 分别使用数据库锁、NoSql 实现分布式锁
→ 性能调优
→ 数据库连接池