Java知识简要提纲

回答问题提纲

记录一下Java八股的简要回答思路。

Java基础

1. 面向对象和面向过程

思想上:具体的过程,抽象化
三大特性:过程--封装  对象三个都有
维护性

2. JVM/JRE/JDK

包含关系     java核心类库    javac 其他类  开发工具  

3. 八大基本类型

1--2---4个字节的变化   char--short--byte 计算时会提升(好像i++不一样)  1个字节8位

4. 重载和重写

运行时多态   编译时多态    是否同一个类   重写的返回类型、方法名、参数列表要求严格

5. 三大特性

封装:属性私有化、提供接口
继承:已有类去继承,属性都是有的,就是可不可以访问(private)
多态:编译时不能确定引用到底指向那个对象  或者说方法属于哪个对象

6. String StringBuilder StringBuffer

可不可变         线程安全       性能上来说String最低    String是final修饰的char数组

7. 静态变量、静态方法、静态代码块

类加载确定、注意执行顺序、属于所有类、静态方法没有重写的概念,其实是两个不同的方法----还是从编译与运行来理解

8. 不做事的无参什么用

super()的调用     注意super和this不可以同时出现

9. 接口与抽象方法

构造方法   是否可有具体方法  是否可有静态方法
修饰符 方法上 抽象类(public protected default)  接口 public  abstract  --------变量上 抽象类除了private都有 接口还有final修饰 
jdk 8 的时候接口可以有默认方法和静态方法功能。
Jdk 9 在接口中引入了私有方法和私有静态方法。

10. ==和equals、hashcode

比较的是内容还是地址,是否重写了equals
hashcode是为了方便对象的比较,重写equals就要重写hashcode方法,因为hashcode()默认对堆上的对象产生独特值,不重写就不会想等。
散列冲突

11. final finally finalize

final 可修饰类、方法、变量
finally 异常处理的最终执行  若是exit()或者未到异常就终止了程序也不会被执行
finalize 垃圾回收使用到

Java集合

1. Collection和Map

List  queue  set
hashmap  treemap  linkedhashmap
有序  可重复  底部的数据结构  是否双端

2. ArrayList和LinkedList

结构上  可变数组 和 双向链表
性能   查询  增删(需要看位置)
线程安全  都不是          
内存空间占用:  ArrayList会预留元素空间   LinkedList 单个元素占用要大,因为指针

3. ArrayList和Vector

主要是线程安全  查找效率

4. ArrayList的扩容机制

构造函数 (空参--空数组、带初始容量--new Object[容量]、 传集合对象)
add方法-----添加元素之前调用ensureCapacityInternal(size+1)方法
ensureCapacityInternal----得到最小扩容量minCapacity=Math.max(DEFAULT_CAPACITY, minCapacity);  DEFAULT_CAPACITY 默认为10 所以没有元素时用add方法后会变成minCapacity为10   然后调用 ensureExplicitCapacity(minCapacity);
ensureExplicitCapacity----判断最小容量是否发于数组的长度,大于了用  grow(minCapacity)开始扩容
要分配的最大数组大小  MAX_ARRAY_SIZE=Integer.MAX_VALUE - 8;
然后计算oldCapacity = elementData.length; 随之将oldCapacity扩大到1.5倍得到newCapacity
比较newCapacity和minCapacity  取较大的那个为新容量
如果newCapacity大于MAX_ARRAY_SIZE,则新容量则为`Integer.MAX_VALUE` 完成!

5. HashMap和Hashtable

线程安全、   效率、    对key、value为null的支持
初始容量和扩容大小  hashtable初始11  扩为2n+1   hashMap初始16  扩为两倍
如果创建给定了初始容量,hashtable会用他,但是HashMap 会将其扩充为 2 的幂次方大小
底层数据结构         Node数组+链表+红黑树----数组+链表

6. HashMap的底层实现

JDK1.8前
	数组加链表  头插
JDK1.8后
	数组+链表+红黑树(注意8和64两个数字)

7. ConcurrentHashMap 和 Hashtable 的区别

实现锁的形式  1.7 分割segment,锁一段数据 每次锁segment
			1.8 Node数组+链表+红黑树  并发控制使用 synchronized 和 CAS 来操作 锁的是Node节点
底层数据结构  1.7 分段数组+链表  1.8 数组+链表/红黑树
			Hashtable 都是数组+链表

多线程

1. 线程与进程

概念  分配资源的单位  程序执行的单位  包含
可以共享堆、方法区    进程轻量级  切换工作负担小

2. 多线程可能的问题

内存泄漏(长生命周期的对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期对象持有它的引用而导致不能被回收。)----单例造成、静态集合类、连接没有关闭(IO、数据库)、内部类持有外部类、缓存泄露
上下文切换 ----执行完CPU时间片,转换到下一个线程,需要对上一个线程的状态保存,以便再加载
死锁----四个条件(资源的互斥性、请求别人的自己的不放、资源不能强行被夺取、有个循环)

3. 线程的生命周期

new  		创建 还没调用start 
runnable  	获得时间片与资源(包含就绪与运行两种状态)
blocked		阻塞,没有获得锁	  
waiting 	等待状态,需要其他线程做出一些指令来唤醒(notify或interrupt)  
time_waiting 带有等待时间
terminated  完成

4. sleep和wait方法

有无主动释放锁
可不可以自己被唤醒

5. 为什么调用 start() 方法,不能直接调用 run() 方法?

new一个线程后,调用start()完成准备工作,获得CPU时间片之后才能对线程运行
调用run就是一个普通方法
调用 start() 方法方可启动线程并使线程进入就绪状态,直接执行 run() 方法的话不会以多线程的方式执行。

6. synchronize

目的:解决多个线程访问资源的同步性,保证一个线程的占有权
效率低的原因:监视器锁(monitor)依赖系统(mutex lock)要从用户态到内核态的转变,比较慢
修饰实例方法(锁当前对象)、静态方法(一个大类的锁)、代码块(指定资源的锁)
实现原理:同步语句块上--加的是monitor对象  enter、exit  锁会有计数器来表明是否被占有
		方法上,ACC_SYNCHRonized标识,标识是一个同步方法

7. JMM

主存  和线程的工作内存
volatile: 可见性  防指指令重排 不保证原子性,一般修饰变量,并且一次锁一个对象

8. ThreadLocal

目的:让线程有自己的独属变量  用get、set方法来访问
原理:主要是ThreadLocalMap,key就是ThreadLocal对象,value就是set方法设置的值
会有内存泄漏:ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,而 value 是强引用。所以,如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。

9. 线程池

好处:减少资源的消耗、提高响应速度、对线程的可管理性提高

10. Runnable接口和Callable接口

有无返回值和抛出异常
工具类 Executors 可以实现 Runnable 对象和 Callable 对象之间的相互转换。(Executors.callable(Runnable task)或 Executors.callable(Runnable task,Object resule))。

11. execute()方法和 submit()方法

execute用于提交不需要返回值的,所以无法判断是否成功
submit提交会返回一个Future对象,用get方法来获得返回值,但是get会阻塞线程

12. 创建线程池

构造方法入手 七大参数
	核心线程  最大线程  存活时间 时间单位  阻塞队列  线程工厂 拒绝策略
Executors的三个方法
 newFixedThreadPool、newSingleThreadPool、newCacheedThreadPool
 
四中拒绝策略:
抛出异常,拒绝处理、交给调用者处理、丢弃新任务、丢弃等待最长的业务

13. Atomic原子类

原子类说简单点就是具有原子/原子操作特征的类。
分类:基本类型、引用类型、数组类型、对象的属性修改类型

14. AQS

是什么:AbstractQueuedSynchronizer 使用来构建锁和同步器的框架
比如:reenterantLock、semephore、countdownlacth、ReentrantReadWriteLock,SynchronousQueue,FutureTask等
原理是:
  核心思想:如果当请求的资源空闲,这请求资源的线程设置为有效的工作线程
  		  资源不空闲,要设计阻塞和唤醒锁分配的机制
  		  用队列去实现阻塞线程的加入,CLH队列(一个虚拟的双向队列)
  		  AQS 使用一个 int 成员变量来表示同步状态,通过内置的 FIFO 队列来完成获取资源线程的排队工作。AQS 使用 CAS 对该同步状态进行原子操作实现对其值的修改。

15. AQS对资源的共享方法

独占   公平锁  非公平锁
共享	 semaphore、cyclicBarrier、countdownlatch、readwritelock	

16. AQS组件的应用

semaphore
countdownlatch
cyclicBarrier

JVM

1. 五个区域

共享:
 堆:放什么--对象实例,数组,垃圾回收的区域 
 方法区:放什么--常量,静态变量,类信息,即时编译器编译的数据
 字符串常量池(在堆)和运行时常量池(在元空间,直接内存内)
线程私有
 虚拟机栈:放什么:局部变量表、方法出口信息、操作数栈、动态链接
   局部变量表--基本类型,对象引用
   		引用:句柄--句柄池(堆中),存在两个指针,一个实例,一个类型信息
   			直接引用---指向地址
   		      对象实例数据(堆):对象中各个实例字段的数据
			  对象类型数据(方法区):对象的类型、父类、实现的接口、方法等
			  静态区(也在方法区中)用来存放静态变量,静态块
 本地方法栈:对应Native服务
 程序计数器:记录字节码的行数
 			 什么是字节码--JVM可以识别的。.java->.class->机器语言

2. 对象创建过程

类加载检查--分配内存--初始化零值--设置对象头--执行init()方法
  双亲委派模型
  内存两种分配方式:指针碰撞    空闲列表
    创建对象的线程安全解决   TLAB区域,即预留的空间;CAS重试
  对应的类型数据的初始值
  年代、锁的信息、属于哪个类、哈希值

3. JVM内存分配与回收

默认是新生代、看对象的大小和存活时间直接进入老年代
回收:几种算法 然后几种垃圾收集器
	判断可不可以回收,
	 可达性分析-GC root对象(哪些呢?---虚拟机栈中引用的对象,方法区中静态变量引用的对象,常量引用的对象,本地方法栈中native方法引用的对象)
	 引用计数法
	 四种引用 强 软 弱 虚
	  软:不够才会回收
	  弱:扫描到了就会回收
	     弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。
	  虚:有个引用队列配合使用
	    有设么用呢?主要用来跟踪对象被垃圾回收的活动

4. 判断常量和是类是否无用可以被回收了?

常量:没有对象引用它了就可以
类:达成三个条件:1. 该类的实例会被回收、类加载器被回收了、对应的java。lang。class对象没有被引用,既无法通过反射来访问该方法了

5. 垃圾回收算法

标记清除   	问题:效率问题和空间碎片
复制        问题:内存小了  (新生代主要在用)
标记整理(老年代主要再用)   
分代收集算法

6. 常见的垃圾回收器

serial:新生代采用复制算法,老年代采用标记-整理算法。
ParNew:新生代采用复制算法,老年代采用标记-整理算法。
Parallel Scavenge:新生代采用复制算法,老年代采用标记-整理算法。
CMS:初始标记、并发标记、重新标记、并发清除

MySQL

1. InnoDB和MyISAM

事务支持、锁的级别、外键支持、储存结构、是否支持MVCC、叶子结点是数据还是指针
仅 InnoDB 支持。应对高并发事务, MVCC比单纯的加锁更高效;MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作;MVCC可以使用 乐观(optimistic)锁 和 悲观(pessimistic)锁来实现;各数据库中MVCC实现并不统一。

2. 索引

B+tree索引 和 哈希索引
哈希:查找快,但是范围不太行
B+树:有效减少IO,叶子结点放数据

3. 事务

四大特性:ACID
问题:脏读、幻读、不可重复读、丢失修改
隔离级别:读取未提交、读取已提交、可重复读、可串行化

4. 锁机制和InnoDB锁算法

两种引擎支持的锁--表级锁、行级锁
锁算法: Record lock:单个行记录的锁
		Gap lock:  间隙锁,锁一个范围,不包括记录本身
		next-key lock :record+gap 锁定一个范围,包含记录本身

相关知识点:

  1. innodb对于行的查询使用next-key lock
  2. Next-locking keying为了解决Phantom Problem幻读问题
  3. 当查询的索引含有唯一属性时,将next-key lock降级为record key
  4. Gap锁设计的目的是为了阻止多个事务将记录插入到同一范围内,而这会导致幻读问题的产生
  5. 有两种方式显式关闭gap锁:(除了外键约束和唯一性检查外,其余情况仅使用record lock) A. 将事务隔离级别设置为RC B. 将参数innodb_locks_unsafe_for_binlog设置为1

5. 大表优化

限定数据的范围(列和行两种) 限制查询、限制结果
读写分离
垂直分区
水平分区
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值