logo资料库

最新2019年蚂蚁课堂每特教育面向java中高级面试宝典.pdf

第1页 / 共149页
第2页 / 共149页
第3页 / 共149页
第4页 / 共149页
第5页 / 共149页
第6页 / 共149页
第7页 / 共149页
第8页 / 共149页
资料共149页,剩余部分请下载后查看
JavaSE
多线程
进程与线程的区别?
为什么要用多线程?
多线程创建方式?
是继承Thread类好还是实现Runnable接口好?
你在哪里用到了多线程?
什么是多线程安全?
如何解决多线程之间线程安全问题?
为什么使用线程同步或使用锁能解决线程安全问题呢?
什么是多线程之间同步?
什么是同步代码块?
多线程同步的分类?
1.使用同步代码块?
2.使用同步函数
3.静态同步函数
同步代码块与同步函数区别?
同步函数与静态同步函数区别?
什么是多线程死锁?
Wait()与Notify ()区别?
Wait()与sleep()区别?
Lock与Synchronized区别?
Condition用法
Condition condition = lock.newCondition();
res. condition.await(); 类似wait
res. Condition. Signal() 类似notify
如何停止线程?
什么是守护线程
join()方法作用
线程三大特性
说说Java内存模型
什么是Volatile作用
什么是AtomicInteger
什么是ThreadLocal
什么是线程池?
线程池作用
线程池四种创建方式
说说JDK1.5并发包
锁的种类
自旋锁
互斥锁
可重入锁
悲观锁
乐观锁
信号量
集合
网络编程
什么是Socket?
TCP与UDP在概念上的区别
设计模式
什么是设计模式?
设计模式的分类?
设计模式的六大原则
单例模式
什么是单例模式?
单例写法
工厂模式
什么是工厂模式?
简单工厂代码
工厂方法
代理模式
什么是代理?
代理应用场景
代理的分类
静态代理
JDK动态代理(不需要生成代理类)
CGLIB动态代理
CGLIB与JDK动态代理区别
其他
什么是注解?
如何定义一个注解?
什么是数据交换格式?
数据交换格式用场景
JSON解析框架有哪些?
XML解析方式?
Dom4j与Sax区别
XML与JSON区别
什么是Java反射
反射机制的作用
反射机制的应用场景
反射机制获取类有三种方法
反射创建对象的方式
反射创建api
使用反射为类私有属性赋值
JVM参数调优
Java虚拟机原理
Java内存结构
堆、栈、方法区概念区别
Java堆
Java栈
Java方法区
虚拟机参数配置
什么是虚拟机参数配置
堆的参数配置
设置最大堆内存
设置新生代与老年代优化参数
设置新生代比例参数
设置新生与老年代代参数
内存溢出解决办法
设置堆内存大小
设置栈内存大小
Tomcat内存溢出在catalina.sh 修改JVM堆内存大小JAVA_OPTS="-serv
内存溢出与内存泄露的区别
JVM参数调优总结
垃圾回收机制
垃圾回收机制概述
垃圾回收简要过程
手动GC回收
finalize作用
垃圾回收机制算法
引用计数法
概述
优缺点
标记清除算法
复制算法
标记-压缩算法
分代收集算法
为什么老年代使用标记压缩、新生代使用复制算法。
垃圾回收时的停顿现象
垃圾收集器
什么是Java垃圾回收器
串行回收器(Serial Collector)
并行回收
并行回收器(ParNew回收器)
并行回收集器(ParallelGC)
并CMS(并发GC)收集器
G1回收器
调优总结
MySQL优化
MySQL如何优化
数据库设计
什么是数据库范式
数据库三大范式
慢查询
什么是慢查询
如何修改慢查询
如何将慢查询定位到日志中
索引
什么是索引
索引的分类
主键索引
创建主键索引
查询索引
全文索引
唯一索引
普通索引
索引的实现原理
索引的代价
那些列上适合添加索引
索引的注意事项
查询所用使用率
SQL调优
MySQL数据引擎
Myisam注意事项
数据库数据备份
手动方式
自动方式
分表分库
垂直拆分
水平拆分
水平分割案例
如何使用水平拆分数据库
使用取摸方式分表
创建一个demo项目
POM文件
Service代码
Controller
什么是读写分离
读写分离的好处
主从复制原理
Scale-up与Scale-out区别
解决问题
环境搭建
MyCat
什么是  Mycat
JavaEE
基础部分
BS与CS区别?
DNS解析过程
外网映射工具
静态资源和动态资源的区别
Sevlet的生命周期(重点)
怎么证明Servlet是单例的?
Servlet的多线程并发问题
转发与重定向区别?
重定向实现原理
JavaWeb有哪些会话技术
Cookie的实现原理
Cookie的应用场景
Session的实现原理
什么是token
如何自定义token
什么是UUID
UUID组成
UUID代码
什么是Filter
网络通讯
http部分
什么是http协议
Http格式的分类
https与http区别
https请求方式
客户端模拟http请求工具
服务器模拟http请求工具
前端ajax请求
框架部分
Spring
Spring概述
SpringBeanId重复会怎么样?
什么是SpringIOC
什么是SpringAOP
SpringAOP创建方式
注解方式实现AOP编程
XML方式实现AOP编程
Spring是单例还是多例?
Spring作用域
singleton 
prototype
request
session
IOC容器创建对象
依赖注入有哪些方式
事物的概述
⑴ 原子性(Atomicity)
⑵ 一致性(Consistency)
⑶ 隔离性(Isolation)
⑷ 持久性(Durability)
Spring事物控制
Spring事物传播行为
SpringBoot
什么是SpringBoot
SpringBoot优点
@RestController
@EnableAutoConfiguration
SpringApplication.run(HelloController.class, args)
Mybatis与Hibernate区别
Mybatis#与$区别
安全与防御部分
表单重复提交解决方案(防止Http重复提交。)
6使用后端提交解决
如何防御XSS攻击
跨域实战解决方案
使用后台response添加header
使用JSONP
使用接口网关
使用内部服务器转发
什么是SQL语句注入
怎么防御DDOC?
nginx配置DDOS
限制请求速度
限制请求速度
缓存部分
什么是NOSQL?
什么是Redis?
Redis应用场景
Redis优势
Redis与其他key-value存储有什么不同?
Redis的基本数据类型
字符串类型(String)
列表类型(List)
集合(Set)
有序集合(sorted set)
哈希(Hash)
什么是redis的主从复制
什么是哨兵机制
Redis事物
Redis持久化
RDB持久化
AOF持久化
AOF与RDB区别
Redis发布订阅
Redis如何做集群?
nginx
什么是nginx
nginx应用场景
nginx优缺点
nginx.conf 介绍
nginx.conf文件的结构
配置静态访问
nginx实现反向代理
什么是反向代理?
Host文件新增
nginx.conf 配置
nginx实现负载均衡
什么是负载均衡
负载均衡策略
配置代码
宕机轮训配置规则
负载均衡服务器有哪些?
nginx解决网站跨域问题
nginx配置防盗链
nginx配置DDOS
限制请求速度
限制请求速度
什么是Keepalived
集群情况下Session共享解决方案
nginx或者haproxy做的负载均衡)
利用数据库同步session
利用cookie同步session数据原理图如下
使用Session集群存放Redis
引入maven依赖
创建SessionConfig
初始化Session
控制器层代码
高并发解决方案
消息中间件
消息中间件产生的背景
什么是消息中间件
JMS介绍
什么是JMS?
什么是消息模型
P2P (点对点)
Pub/Sub (发布与订阅)
MQ产品的分类
RabbitMQ
Redis
ZeroMQ
ActiveMQ
Jafka/Kafka
MQ怎么保证消息幂等问题
MQ有哪些协议
微服务与分布式
什么是RPC远程调用?
什么是SOA?与SOAP区别是什么?
什么是微服务架构
微服务与SOA区别
RPC远程调用有哪些框架?
什么是SpringCloud
什么是Dubbo?
Dubbo有哪些协议?
Dubbo整个架构流程
Dubbox与Dubbo区别?
SpringCloud与Dubbo区别?
相同点:
区别:
什么是Zookeeper
Zookeeper特点
zookeeper的数据模型
Zookeeper应用场景
什么是分布式锁
Zookeeper实现分布式锁
Redis分布式锁思考
Zookeeper与 Redis实现分布式锁的区别
基于缓存实现分布式锁
基于Zookeeper实现分布式锁
Java实现定时任务有哪些方式
Thread
TimerTask
ScheduledExecutorService
Quartz
创建一个quartz_demo项目
引入maven依赖
任务调度类
启动类
分布式情况下定时任务会出现哪些问题?
分布式定时任务解决方案
分布式事物解决方案
全局事物
本地消息表
MQ(非事物)
MQ(事务消息)
其他补偿方式
补充资料
什么是两段提交协议
一、协议概述
二、执行过程
三、协议的特点
四、工作过程
项目问题
支付项目支付流程
支回调怎么保证幂等性
支回调数据安全性
正回调中,项目宕机。
网页授权OAuth2.
你们登录流程
你在开发中遇到了那些难题,是怎么解决的?
跨域
使用后台response添加header
使用JSONP
使用接口网关
使用内部服务器转发
同步接口中保证数据一致性问题
任务调度幂等性问题
MQ幂等性问题
蚂蚁课堂创始人-余胜军原创制作,其他网站转载请说明原创作者,QQ644064779 Java 高级工程师面试宝典 JavaSE 多线程 进程与线程的区别? 答:进程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只 是一条执行路径。 为什么要用多线程? 答:提高程序效率 多线程创建方式? 答:继承 Thread 或 Runnable 接口。 是继承 Thread 类好还是实现 Runnable 接口好? 答:Runnable 接口好,因为实现了接口还可以继续继承。继承 Thread 类不能再 继承。 你在哪里用到了多线程? 答:主要能体现到多线程提高程序效率。 举例:分批发送短信、迅雷多线程下载等。 什么是多线程安全? 答:当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就 是线程安全问题。做读操作是不会发生数据冲突问题。
蚂蚁课堂创始人-余胜军原创制作,其他网站转载请说明原创作者,QQ644064779 如何解决多线程之间线程安全问题? 答:使用多线程之间同步或使用锁(lock)。 为什么使用线程同步或使用锁能解决线程安全问题呢? 答:将可能会发生数据冲突问题(线程不安全问题),只能让当前一个线程进行执行。被包裹的代码执行完 成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。 什么是多线程之间同步? 答:当多个线程共享同一个资源,不会受到其他线程的干扰。 什么是同步代码块? 答:就是将可能会发生线程安全问题的代码,给包括起来。只能让当前一个 线程进行执行,被包裹的代码执行完成之后才能释放所,让后才能让其他线程进 行执行。 多线程同步的分类? 1.使用同步代码块? synchronized(同一个数据){ 可能会发生线程冲突问题 } private Object mutex = new Object();// 自定义多线程同步锁 public void sale() { synchronized (mutex) { if (trainCount > 0) { try { Thread.sleep(10); } catch (Exception e) { } System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票."); trainCount--; } } }
蚂蚁课堂创始人-余胜军原创制作,其他网站转载请说明原创作者,QQ644064779 2.使用同步函数 在方法上修饰 synchronized 称为同步函数 public synchronized void sale() { if (trainCount > 0) { try { Thread.sleep(40); } catch (Exception e) { } System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票."); trainCount--; } } 3.静态同步函数 方法上加上 static 关键字,使用 synchronized 关键字修饰 为静态同步函数 静态的同步函数使用的锁是 该函数所属字节码文件对象 同步代码块与同步函数区别? 答: 同步代码使用自定锁(明锁) 同步函数使用 this 锁 同步函数与静态同步函数区别? 注意:有些面试会这样问:例如现在一个静态方法和一个非静态静态怎么实现同步? 答: 同步函数使用 this 锁 静态同步函数使用字节码文件,也就是类.class 什么是多线程死锁? 答: 同步中嵌套同步,无法释放锁的资源。 解决办法:同步中尽量不要嵌套同步
蚂蚁课堂创始人-余胜军原创制作,其他网站转载请说明原创作者,QQ644064779 Wait()与 Notify ()区别? Wait 让当前线程有运行状态变为等待状态,和同步一起使用 Notify 唤醒现在正在等待的状态,和同步一起使用 Wait()与 sleep()区别? 对于 sleep()方法,我们首先要知道该方法是属于 Thread 类中的。而 wait()方法,则是属于 Object 类中 的。 sleep()方法导致了程序暂停执行指定的时间,让出 cpu 该其他线程,但是他的监控状态依然保持者,当 指定的时间到了又会自动恢复运行状态。 在调用 sleep()方法的过程中,线程不会释放对象锁。 而当调用 wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用 notify()方法后本线程才进入对象锁定池准备 获取对象锁进入运行状态。 Lock 与 Synchronized 区别? Lock 接口可以尝试非阻塞地获取锁 当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成 功获取并持有锁。 *Lock 接口能被中断地获取锁 与 synchronized 不同,获取到锁的线程能够响应中断,当获取到的锁的 线程被中断时,中断异常将会被抛出,同时锁会被释放。 Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。 Condition 用法 Condition 的功能类似于在传统的线程技术中的,Object.wait()和 Object.notify()的功能, 代码: Condition condition = lock.newCondition(); res. condition.await(); 类似 wait res. Condition. Signal() 类似 notify Signalall notifyALL 如何停止线程? 1. 使用退出标志,使线程正常退出,也就是当 run 方法完成后线程终止。
蚂蚁课堂创始人-余胜军原创制作,其他网站转载请说明原创作者,QQ644064779 2. 使用 stop 方法强行终止线程(这个方法不推荐使用,因为 stop 和 suspend、resume 一样,也可能 发生不可预料的结果)。 3. 使用 interrupt 方法中断线程。 线程在阻塞状态 什么是守护线程 Java 中有两种线程,一种是用户线程,另一种是守护线程。 当进程不存在或主线程停止,守护线程也会被停止。 使用 setDaemon(true)方法设置为守护线程 join()方法作用 join 作用是让其他线程变为等待,只有当前线程执行完毕后,等待的线程才会被释放。 线程三大特性 多线程有三大特性,原子性、可见性、有序性 原子性:保证数据一致性,线程安全。 可见性:对另一个线程是否课件 有序性:线程之间执行有顺序 说说 Java 内存模型 共享内存模型指的就是 Java 内存模型(简称 JMM),JMM 决定一个线程对共享变量的写入时, 能对另一个线程可见。从抽象的角度来看,JMM 定义了线程和主内存之间的抽象关系:线 程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存 (local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是 JMM 的一 个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优 化。
蚂蚁课堂创始人-余胜军原创制作,其他网站转载请说明原创作者,QQ644064779 什么是 Volatile 作用 Volatile 关键字的作用是变量在多个线程之间可见。 什么是 AtomicInteger AtomicInteger 原子类 什么是 ThreadLocal ThreadLocal 提高一个线程的局部变量,访问某个线程拥有自己局部变量。 当使用 ThreadLocal 维护变量时,ThreadLocal 为每个使用该变量的线程提供独立的变量副 本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 ThreadLocal 的接口方法 ThreadLocal 类接口很简单,只有 4 个方法,我们先来了解一下: void set(Object value)设置当前线程的线程局部变量的值。 public Object get()该方法返回当前线程所对应的线程局部变量。 public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是 JDK 5.0 新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾 回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收 的速度。 protected Object initialValue()返回该线程局部变量的初始值,该方法是一个 protected 的方法, 显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第 1 次调用 get() 或 set(Object)时才执行,并且仅执行 1 次。ThreadLocal 中的缺省实现直接返回一个 null。 什么是线程池? 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的 任务时重用这些线程而不是新建一个线程。线程池中线程的数量通常完全取决于可用内存数 量和应用程序的需求。然而,增加可用线程数量是可能的。线程池中的每个线程都有被分配 一个任务,一旦任务已经完成了,线程回到池子中并等待下一次分配任务。 线程池作用 基于以下几个原因在多线程应用程序中使用线程是必须的: 1. 线程池改进了一个应用程序的响应时间。由于线程池中的线程已经准备好且等待被分配 任务,应用程序可以直接拿来使用而不用新建一个线程。 2. 线程池节省了 CLR 为每个短生存周期任务创建一个完整的线程的开销并可以在任务完
蚂蚁课堂创始人-余胜军原创制作,其他网站转载请说明原创作者,QQ644064779 成后回收资源。 3. 线程池根据当前在系统中运行的进程来优化线程时间片。 4. 线程池允许我们开启多个任务而不用为每个线程设置属性。 5. 线程池允许我们为正在执行的任务的程序参数传递一个包含状态信息的对象引用。 6. 线程池可以用来解决处理一个特定请求最大线程数量限制问题。 线程池四种创建方式 Java 通过 Executors(jdk1.5 并发包)提供四种线程池,分别为: newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收 空闲线程,若无可回收,则新建线程。 newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中 等待。 newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。 newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 说说 JDK1.5 并发包 名称 Lock Executors ReentrantLock Condition ConcurrentHashMap AtomicInteger BlockingQueue ExecutorService 锁的种类 自旋锁 作用 锁 线程池 一个可重入的互斥锁定 Lock,功能类似 synchronized, 但要强大的多。 Condition 的 功 能 类 似 于 在 传 统 的 线 程 技 术 中 的,Object.wait()和 Object.notify()的功能, 分段 HasMap 原子类 BlockingQueue 通常用于一个线程生产对象,而另外一 个线程消费这些对象的场景 执行器服务 自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时
蚂蚁课堂创始人-余胜军原创制作,其他网站转载请说明原创作者,QQ644064779 才能进入临界区。如下 public class SpinLock { private AtomicReference sign = new AtomicReference<>(); public void lock() { Thread current = Thread.currentThread(); while (!sign.compareAndSet(null, current)) { } } public void unlock() { Thread current = Thread.currentThread(); sign.compareAndSet(current, null); } } 互斥锁 所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在 jdk1.5 之前, 我们通常使用 synchronized 机 制控制多个线程对共享资源 Lock 接口及其实现类 ReentrantLock 可重入锁 可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获 取该锁的代码,但不受影响。 在 JAVA 环境下 ReentrantLock 和 synchronized 都是 可重入锁 悲观锁 .悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部 系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。 悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证 数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系 统不会修 改数据)。 乐观锁 相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库 的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库 性能的大量开销,
分享到:
收藏