09 Java面试总结
文章
01 类型转换
基本类型的类型转换继承中的类型转换 向上转型。子类的对象可以转换成父类的变量。 向下转型。父类的变量可以转换成子类的变量。 验证3种情况 父类变量指向父类对象(父类方法)。父类变量强制转换子类变量(转换出错)。 子类变量指向子类对象(子类方法)。子类变量强制转换父类变量(多态子类方法)。 父类变量指向子类对象(多态子类方法)。父类变量强制转换子类变量(子类方法)。 1234567891011121314151617public class App02{ public static void main( String[] args ) { System.out.println( "Hello World!" ); Dog dd = new Dog(); Animal aa = new Animal(); Animal ad = new Dog(); dd.say(); //dog say ((Animal)dd).say();//dog s...
01.String 是如何实现的?它有哪些重要的方法?
String 是如何实现的?它有哪些重要的方法?几乎所有的 Java 面试都是以 String 开始的,如果第一个问题没有回答好,则会给面试官留下非常不好的第一印象,而糟糕的第一印象则会直接影响到自己的面试结果,就好像刚破壳的小鹅一样,会把第一眼看到的动物当成自己的母亲,即使它第一眼看到的是一只小狗或小猫,也会默认跟随其后,心理学把这种现象叫做印刻效应。印刻效应不仅存在于低等动物之中,同样也适用于人类,所以对于 String 的知识,我们必须深入的掌握才能为自己赢得更多的筹码。 本课时的问题是:String 是如何实现的?它有哪些重要的方法? 典型回答以主流的 JDK 版本 1.8 来说,String 内部实际存储结构为 char 数组,源码如下: 1234567public final class String implements java.io.Serializable,Comparable<String>,CharSequence{ //用于存储字符串的值 private final charvalue[]; //缓存字符串的 ha...
02.HashMap 底层实现原理是什么?JDK8 做了哪些优化?
HashMap 底层实现原理是什么?JDK8 做了哪些优化?HashMap 是使用频率最高的类型之一,同时也是面试经常被问到的问题之一,这是因为 HashMap 的知识点有很多,同时它又属于 Java 基础知识的一部分,因此在面试中经常被问到。 本课时的面试题是,HashMap 底层是如何实现的?在 JDK 1.8 中它都做了哪些优化? 典型回答在JDK1.7中HashMap是以数组加链表的形式组成的,JDK1.8之后新增了红黑树的组成结构,当链表大于8时,链表结构会转换成红黑树结构,它的组成结构如下图所示: 数组中的元素我们称之为哈希桶,它的定义如下: 123456789101112131415161718192021222324252627282930313233343536373839static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V&...
03 关键字
类别 关键字 说明 访问控制 private 私有的 protected 受保护的 public 公共的 default 默认 类、方法和变量修饰符 abstract 声明抽象 class 类 extends 扩充,继承 final 最终值,不可改变的 implements 实现(接口) interface 接口 native 本地,原生方法(非 Java 实现) new 新,创建 static 静态 strictfp 严格,精准 synchronized 线程,同步 transient 短暂 volatile 易失 程序控制语句 break 跳出循环 case 定义一个值以供 switch 选择 continue 继续 default 默认 do 运行 else 否则 for 循环 if 如果 instanceof 实例 return 返回 switch 根据值选择执行 while 循环 错误处理 assert 断言表达式是否为真 catch 捕捉异...
03.线程的状态有哪些?它是如何工作的?
线程的状态有哪些?它是如何工作的?线程(Thread)是并发编程的基础,也是程序执行的最小单元,它依托进程而存在。一个进程中可以包含多个线程,多线程可以共享一块内存空间和一组系统资源,因此线程之间的切换更加节省资源、更加轻量化,也因此被称为轻量级的进程。 当然,线程也是面试中常被问到的一个知识点,是程序员必备的基础技能,使用它可以有效地提高程序的整体运行速度。 本课时的面试问题是,线程的状态有哪些?它是如何工作的? 典型回答线程的状态在 JDK 1.5 之后以枚举的方式被定义在 Thread 的源码中,它总共包含以下 6 个状态: NEW,新建状态,线程被创建出来,但尚未启动时的状态; RUNNABLE,就绪状态,表示可以运行的线程状态,它可能正在运行,或者是排队等待CPU分配给它资源; BLOCKED,阻塞等待锁的线程状态,表示处于阻塞状态的线程正在等待监视器锁,比如等待执行synchronized代码块或者使用synchronized标记的方法; WAITING,等待状态,一个处于等待状态的线程正在等待另一个线程执行某个特定的动作,比如,一个线程调用了Object.wait...
04 缓存穿透、击穿和雪崩
在生产环境中,会因为很多的原因造成访问请求绕过了缓存,都需要访问数据库持久层,虽然对Redsi缓存服务器不会造成影响,但是数据库的负载就会增大,使缓存的作用降低 1 缓存穿透1、缓存穿透理解缓存穿透是指查询一个根本不存在的数据,缓存层和持久层都不会命中。在日常工作中出于容错的考虑,如果从持久层查不到数据则不写入缓存层,缓存穿透将导致不存在的数据每次请求都要到持久层去查询,失去了缓存保护后端持久的意义。 缓存穿透示意图:  缓存穿透问题可能会使后端存储负载加大,由于很多后端持久层不具备高并发性,甚至可能造成后端存储宕机。通常可以在程序中统计总调用数、缓存层命中数、如果同一个Key的缓存命中率很低,可能就是出现了缓存穿透问题。 造成缓存穿透的基本原因有两个。第一,自身业务代码或者数据出现问题(例如:set 和 get 的key不一致),第二,一些恶意攻击、爬虫等造成大量空命中(爬取线上商城商品数据,超大循环递增...
04 修饰符
0 修饰符概述Java 常见的修饰符 访问控制修饰符default,private,public,protected 非访问控制修饰符static/final/abstract/sychronized/transient/volatile 1 访问控制修饰符修饰符的作用 默认访问修饰符-不使用任何关键字。使用默认访问修饰符声明的变量和方法,对同一个包内的类是可见的。接口里的变量都隐式声明为 public static final,而接口里的方法默认情况下访问权限为 public 私有访问修饰符-private。私有访问修饰符是最严格的访问级别,所以被声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。声明为私有访问类型的变量只能通过类中公共的 getter 方法被外部类访问。private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。 公有访问修饰符-public。被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。如果几个相互访问的 publ...
04.详解 ThreadPoolExecutor 的参数含义及源码执行流程?
详解 ThreadPoolExecutor 的参数含义及源码执行流程?线程池是为了避免线程频繁的创建和销毁带来的性能消耗,而建立的一种池化技术,它是把已创建的线程放入“池”中,当有任务来临时就可以重用已有的线程,无需等待创建的过程,这样就可以有效提高程序的响应速度。但如果要说线程池的话一定离不开**ThreadPoolExecutor,在阿里巴巴的《Java开发手册》中是这样规定线程池的:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor**的方式,这样的处理方式让写的读者更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors 返回的线程池对象的弊端如下: 1)FixedThreadPool 和 SingleThreadPool:允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM(Out Of Memory) 2)CachedThreadPool 和 ScheduledThreadPool:允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 ...
05.synchronized和ReentrantLock
synchronized 和 ReentrantLock 的实现原理是什么?它们有什么区别?在 JDK 1.5 之前共享对象的协调机制只有 synchronized 和 volatile,在 JDK 1.5 中增加了新的机制 ReentrantLock,该机制的诞生并不是为了替代 synchronized,而是在 synchronized 不适用的情况下,提供一种可以选择的高级功能。 典型回答synchronized 属于独占式悲观锁,是通过 JVM 隐式实现的,synchronized 只允许同一时刻只有一个线程操作资源。 在 Java 中每个对象都隐式包含一个 monitor(监视器)对象,加锁的过程其实就是竞争 monitor 的过程,当线程进入字节码 monitorenter 指令之后,线程将持有 monitor 对象,执行 monitorexit 时释放 monitor 对象,当其他线程没有拿到 monitor 对象时,则需要阻塞等待获取该对象。 ReentrantLock 是 Lock 的默认实现方式之一,它是基于 AQS(Abstract Queued Sync...
06.谈谈你对锁的理解?如何手动模拟一个死锁?
谈谈你对锁的理解?如何手动模拟一个死锁?在并发编程中有两个重要的概念:线程和锁,多线程是一把双刃剑,它在提高程序性能的同时,也带来了编码的复杂性,对开发者的要求也提高了一个档次。而锁的出现就是为了保障多线程在同时操作一组资源时的数据一致性,当我们给资源加上锁之后,只有拥有此锁的线程才能操作此资源,而其他线程只能排队等待使用此锁。当然,在所有的面试中也都少不了关于“锁”方面的相关问题。 典型回答死锁是指两个线程同时占用两个资源,又在彼此等待对方释放锁资源,如下图所示: 死锁的代码演示如下: 12345678910111213141516171819202122232425262728293031323334353637383940414243import java.util.concurrent.TimeUnit;public class LockExample { public static void main(String[] args) { deadLock(); // 死锁 }/** * 死锁 */private s...














