samwellwang

samwellwang

coder
twitter

Java 面试问题与分析

想要系统和全面的学习一下 Java,毕竟现在在学校也没有学到啥有用的,那就想说从面试题开始吧,反正不就之后也要找工作。

想要系统和全面的学习一下 Java,毕竟现在在学校也没有学到啥有用的,那就想说从面试题开始吧,反正不就之后也要找工作。LeetCode 对我来说还是太难了,但以后也一定要开一篇博客来学习 LeetCode 的。现在就从简单的面试题开始(其实也不简单。随便在网上找了一个 Java 最常见的 200+ 面试题来参考,查漏补缺,一道一道的攻克!

Java 基础#

1.JDK 和 JRE 有什么区别?#

这个简单,JDL 是 Java Development Kit Java 开发工具套装,面向开发人员,包含 JRE 和 Java 工具 (javac 等) 以及 Java 基础类库。JRE 是 Java Runtime Environment。Java 运行环境。面向使用 java 的人。包含 jvm java 虚拟机和核心的类库。

2.== 和 equals 的区别是什么?#

首先 == 是比较运算符,equals 是 Object 类提供的方法。equals 可以被重写 override, 也经常被重写。在没有被重写的情况下,== 和 equals 是同等作用。当 equals 被重写了就要具体分析。原理基本上就是 == 运算符比较的是基本类型的时候比较的是他们的值,引用类型的时候比较的是两个变量的内存地址。equals 一般比较的内存地址指向的值。不能用于基本类型的比较。比较常见的就是 String 下的 equals 比较的是字符串是否相同。
对于 Integer 和 int 看以下的代码就能回忆起差别

 public static void main(String[] args) {
    //-128 ~ +127 之间
    Integer a = 5;
    int b = 5;
    Integer c = new Integer(5);
    Integer d = 5;

    System.out.println(a.equals(b));
    System.out.println(a == b);
    System.out.println(a.equals(c));
    System.out.println(a == c);
    System.out.println(a == d);

    //-128 ~ +127 之外
    a = 128;
    b = 128;
    c = new Integer(128);
    d = 128;

    System.out.println(a.equals(b));
    System.out.println(a == b);
    System.out.println(a.equals(c));
    System.out.println(a == c);
    System.out.println(a == d);
}

答案:

//-128 ~ +127 之间
True True True False True  
//-128 ~ +127 之外  
True True True False False

3. 两个对象的 hashCode () 相同,则 equals () 也一定为 true,对吗?#

首先是肯定不一定,因为两个方法都可以被重写,完全在于自己。
hashCode () 返回该对象的哈希码值;equals () 返回两个对象是否相等。但是对于 hashCode 和 equal 是方法是 Java 官方文档有一些常规协定的 :

  • 1、两个对象用 equals () 比较返回 true,那么两个对象的 hashCode () 方法必须返回相同的结果。

  • 2、两个对象用 equals () 比较返回 false,不要求 hashCode () 方法也一定返回不同的值,但是最好返回不同值,亿提搞哈希表性能。

  • 3、重写 equals () 方法,必须重写 hashCode () 方法,以保证 equals 方法相等时两个对象 hashcode 返回相同的值。

    4.final 在 java 中有什么作用?#

  • 修饰类不可以被继承

  • 修饰方法不能被 Override

  • 修饰变量就是常量不能被赋值。
    修饰基本数据类型数值不可以改变,修改引用数据类型不能改变地址,但是地址指向的数据可以被修改的。final 修饰变量的本质: final 修饰的变量会指向一块固定的内存,这块内存中的值不能改变.

    5.java 中的 Math.round (-1.5) 等于多少?#

    答案是 -1, Round 函数是直接加 0.5 然后向下取整 - 1.5+0.5=-1 向下取整为 - 1。

    -1.4+0.5=-0.9 向下取整 - 1。-1.6+0.5=-1.1 向下取整为 - 2

    6.String 属于基础的数据类型吗?#

    明显不属于,String 是一个对象,引用类型的。Java 基础类型只有:
    byte

  • 8 位有符号的,以二进制补码表示的整数

  • 最小是 - 128(-2^7),最大是 127(2^7-1),默认值是 0

  • byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一

  • 例子:byte a = 100,byte b = -50
    short

  • 16 位有符号的,以二进制补码表示的整数

  • 最小值是 - 32768 (-2^15), 最大为 32767(2^15-1)默认值 0

  • short 变量所占空间是 int 的二分之一

  • 例子:short s = 1000,short r = -20000
    int

  • 32 位有符号的,以二进制补码表示的整数

  • 最小值为 - 2147483648(-2^31), 最大值为 2147483647(2^31-1)

  • 默认值为 0 一般整型默认也为 0
    long

  • 64 位有符号的,以二进制补码表示的整数

  • 最小值为(-2^63),最大值为(2^63-1),默认值为 0L

  • 例子: long a = 100000L,Long b = -200000L

  • 这种类型主要使用在需要比较大整数的系统上
    float

  • float 是单精度,32 位,符合 IEEE 754 标准的浮点数

  • float 在储存大型浮点数组的时候可以节省内存

  • 默认值为 0.0f,浮点数不能用来表示精确的值,如货币。

  • 例子,float f1=0.2f
    double

  • double 是双精度,64 位符合 IEEE 754 标准的浮点数

  • 浮点数默认为 double,同样不能表示精确的值

  • 默认值为 0.0d

  • 例子,double d1=0.2d。
    boolean

  • boolean 表示 1 位的信息

  • 只有俩值,true OR false

  • 默认值为 false

  • 例子 boolean b = true
    char

  • char 类型是一个单一的 16 位 Unicode 字符

  • 最小值是 \ u0000(就是 0)最大值为 \ uffff (65535)

  • char 可以储存任何字符。

  • 例子,char A=’A’;
    以上基本类型信息整理自菜鸟教程

    7.java 中操作字符串都有哪些类?它们之间有什么区别?#

    三种都是以 char [] 形式保存的字符串。

  • String: 不支持修改,修改相当于重新创建一个对象。

  • StringBuffer:线程安全,多线程使用。没必要使用。

  • StringBuilder:线程不安全,但是快,单线程使用。

    8.String str=”i” 与 String str=new String (“i”) 一样吗?#

    回到 2 号问题了,equals () 是相等的,但是做 == 运算结果是 false,因为 str=”i” 时 java 虚拟机将”i” 分配到常量池中,常量池中没有重复元素,如果再有一个变量比如 str2=”i”,则将常量池中的”i” 的地址分配给 str2,没有就在创建一个,而 new 一个对象则分配到堆内存中,即使值是一样的,但是地址不同。

    9. 如何将字符串反转?#

    StringBuffer 和 StringBuilder 的 reverse () 方法。或者转为 char 数组做循环。

    10.String 类的常用方法都有那些?#

  • int indexOf()

  • int length(String ch)

  • String subString (int beginIndex,int endIndex), 包前不包后

  • String trim()

  • boolean equals()

  • toLowerCase(),toUpperCase()

  • char charAt(int index)

  • String [] split (String regex, int limit) 第一个参数是分割依据,第二个是分割份数。

  • 还有很多懒得写了…. 很少用。

    11. 抽象类必须要有抽象方法吗?#

    不是的,被 abstract 修饰的就是抽象类,可以不含有抽象方法,如果含有一个抽象方法就必须是抽象类。就算没有抽象方法也不能被实例化。

    12. 普通类和抽象类有哪些区别?#

    普通类可以被实例化,抽象类不可以。抽象类的子类必须实现抽象类的所有抽象方法,除非这个子类也是抽象类。

    13. 抽象类能使用 final 修饰吗?#

    absolutely NO ! 被 final 修饰不能被继承,那抽象类的意思是啥?抽象类不就是要被继承的嘛… 什么鬼问题

    14. 接口和抽象类有什么区别?#

    接口可以理解为抽象类的抽象,全都是抽象方法。一个类只能继承一个抽象类,但是可以继承多个接口。这不就实现多重继承了么….

    15.java 中 IO 流分为几种?#

    终于到我的知识盲区了。。
    输入流,输出流 继续划分字节流,字符流 继续划分节点流,处理流

  • 输入流

    • 输入字符流 Reader
      • 节点流 FileReader,PipedReader,CharArrayReader
      • 处理流 BufferedReader,InputStreamReader
    • 输入字节流 InputStream
      • 节点流 FileInputSteam,PipedInputStream,ByteArrayInputStream
      • 处理流 BufferedInputStream,DataInputStream,ObjectInputStream,SequenceInputStream
  • 输出流

    • 输出字符流 Writer
      • 节点流 FileWriter,PipedWriter,CharArrayWriter
      • 处理流 BufferedWriter,OutputStreamWriter,PrintWriter
    • 输出字节流 OutputStream
      • 节点流 FileOutputStream,PipedOutputStream,ByteArrayOutputStream
      • 处理流 BufferedOutputStream,DataOutputStream,ObjectOutputStream,PrintStream

16.BIO、NIO、AIO 有什么区别?#

IO 的方式通常分为几种,同步阻塞的 BIO、同步非阻塞的 NIO、异步非阻塞的 AIO。
也是盲区~查了资料也不是很懂,需要继续深入了解一下了。

17.Files 的常用方法都有哪些?#

  • Files.exists () 检测文件路径是否存在

  • Files.creatFile () 创建文件

  • Files.ceratDirectory () 创建文件夹

  • Files.delete () 删除文件

  • Files.copy () 复制文件

  • Files.move () 移动文件

  • Files.size () 查看文件个数

  • Files.read () 读取文件

  • Files.write () 写入文件

    二、容器#

    java 容器都有哪些?#

    List、Set、Map,queue,stack;

    Collection 和 Collections 有什么区别?#

    Collection 是集合的接口,比如 list,set 等就继承于他,
    Collections 是工具类(sort,addAll,max),创建空集合

    List、Set、Map 之间的区别是什么?#

    List 是一种有序列表,和数组差不多。按照放入顺序存放。
    Set 是储存不重复元素集合,相当于只存 map 中的 key。
    Map 是 key-value 键值对形式。

    HashMap 和 Hashtable 有什么区别?#

    HashMap 不同步,线程不安全,但是效率快。发布的晚 1.2 后才有
    Hashtable 基本不用了 ,除了 Properties 是从 Hashtable 继承的。而且没用驼峰命名 哈哈哈

    如何决定使用 HashMap 还是 TreeMap?#

    不需要对 key 排序用 HashMap, 需要用 TreeMap;

    说一下 HashMap 的实现原理?#

    HashMap 是数组加链表的方式实现的,对 key 进行 hashCode()运算得到一个哈希值和数组的长度做取余运算的到索引也就是插入数组中的位置,用的是链表发处理哈西碰撞,就是遇到同一个索引的时候就看一下 key 值是否相同(equals),如果相同就说明通过 key 值一样,就替换原来的 value 值。如果不一样就放到这个链表的下一节点。

    说一下 HashSet 的实现原理?#

    就是对 HashMap 的封装,放一个不变的 Object 当做 value

    ArrayList 和 LinkedList 的区别是什么?#

    ArrayList 底层是数组实现的,LinkedList 是链表实现的。所以优缺点也很明显。ArrayList 查快。LinkedList 增删快。

    如何实现数组和 List 之间的转换?#

    数组转 List:Arrays.asList ()
    List 转数组: list.toArray ()

    ArrayList 和 Vector 的区别是什么?#

    Vector 线程安全的 list 基本不用了。

    Array 和 ArrayList 有何区别?#

    数组是能放基本数据类型和对象类型而且只能放一种,ArrayList 只能放对象类型但不使用泛型可以放多种类型的
    ArrayList 是基于动态数组实现的,大小不固定,Array 固定。

    ArrayList 的扩容机制#

    ArrayList 扩容的本质就是计算出新的扩容数组的 size 后实例化,并将原有数组内容复制到新数组中去。

    在 Queue 中 poll () 和 remove () 有什么区别?#

    都是删除并返回队首元素,remove 要是队列为空报错(抛 NoSuchElementException 异常),但是 poll 会返回 false 或 null。

    哪些集合类是线程安全的?#

    Vector,Hashtable,Stack

    迭代器 Iterator 是什么?#

    迭代器,遍历集合用的工具

    Iterator 怎么使用?有什么特点?#

    next 下一个元素,hasNext 是否有下一个,remove 删除返回的元素

    Iterator 和 ListIterator 有什么区别?#

    Iterator 可以遍历 set map list ListIterator 只能遍历 List 但是可以前后遍历。

    怎么确保一个集合不能被修改?#

    Collections.unmodifiableList(List)

    三、多线程#

    并行和并发有什么区别?#

    • 并行:多个处理器同时处理多个不同的任务。这是物理上的同时发生。

    • 并发:一个处理器可以同时处理多个任务。这是逻辑上的同时发生。
      eg:并发:一个人同时吃三个苹果。并行:三个人同时吃三个苹果。

      线程和进程的区别?#

      进程是一个任务,线程是进程的子任务。操作系统调度的最小任务单位是线程

      守护线程是什么?#

      守护线程是指为其他线程服务的线程。在 JVM 中,所有非守护线程都执行完毕后,无论有没有守护线程,虚拟机都会自动退出。
      因此,JVM 退出时,不必关心守护线程是否已结束。

      创建线程有哪几种方式?#

    1. 继承 Thread 类创建线程类:从 Thread 派生一个自定义类,然后覆写 run () 方法:
    2. 通过 Runnable 接口创建线程类:创建 Thread 实例时,传入一个 Runnable 实例:
    3. 通过 Callable 和 Future 创建线程:

    说一下 runnable 和 callable 有什么区别?#

    1、如上面代码所示,callable 的核心是 call 方法,允许返回值,runnable 的核心是 run 方法,没有返回值

2、call 方法可以抛出异常,但是 run 方法不行

3、因为 runnable 是 java1.1 就有了,所以他不存在返回值,后期在 java1.5 进行了优化,就出现了 callable,就有了返回值和抛异常

线程有哪些状态?#

  • New:新创建的线程,尚未执行;

  • Runnable:运行中的线程,正在执行 run () 方法的 Java 代码;

  • Blocked:运行中的线程,因为某些操作被阻塞而挂起;

  • Waiting:运行中的线程,因为某些操作在等待中;

  • Timed Waiting:运行中的线程,因为执行 sleep () 方法正在计时等待;

  • Terminated:线程已终止,因为 run () 方法执行完毕。

    sleep () 和 wait () 有什么区别?#

    notify () 和 notifyAll () 有什么区别?#

    线程的 run () 和 start () 有什么区别?#

    创建线程池有哪几种方式?#

    线程池都有哪些状态?#

    线程池中 submit () 和 execute () 方法有什么区别?#

    在 java 程序中怎么保证多线程的运行安全?#

    多线程锁的升级原理是什么?#

    什么是死锁?#

    怎么防止死锁?#

    ThreadLocal 是什么?有哪些使用场景?#

    说一下 synchronized 底层实现原理?#

    synchronized 和 volatile 的区别是什么?#

    synchronized 和 Lock 有什么区别?#

    synchronized 和 ReentrantLock 区别是什么?#

    说一下 atomic 的原理?#

    四、反射#

    什么是反射?#

    反射就是 Reflection,Java 的反射是指程序在运行期可以拿到一个对象的所有信息。,为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法。Reflection 是 Java 被视为动态(或准动态)语言的一个关键性质。这种通过 Class 实例获取 class 信息的方法称为反射(Reflection)。

    什么是 java 序列化?什么情况下需要序列化?#

    把对象放到 io 中,实现 serializable 接口
    序列化是指把一个 Java 对象变成二进制内容,本质上就是一个 byte [] 数组。

    动态代理是什么?有哪些应用?#

    JDK 提供的动态创建接口对象的方式,就叫动态代理。
    不编写实现类,直接在运行期创建某个 interface 的实例
    通过 Proxy 创建代理对象,并将接口方法代理给了
    InvocationHandler handler,动态代理的应用有 spring aop、hibernate 数据查询、测试框架的后端 mock、rpc,Java 注解对象获取等。

    怎么实现动态代理?#

  1. 定义一个 InvocationHandler 实例,它负责实现接口的方法调用;
  2. 通过 Proxy.newProxyInstance () 创建 interface 实例,它需要 3 个参数:
  • 使用的 ClassLoader,通常就是接口类的 ClassLoader;
  • 需要实现的接口数组,至少需要传入一个接口进去;
  • 用来处理接口方法调用的 InvocationHandler 实例。
  1. 将返回的 Object 强制转型为接口。

五、对象拷贝#

为什么要使用克隆?#

如何实现对象克隆?#

实现 cloneable 接口,重写 clone ();

深拷贝和浅拷贝区别是什么?#

浅拷贝引用对象属性指向原对象的内存地址;
深拷贝就是完全新的,引用的其他对象也被复制。

六、Java Web#

jsp 和 servlet 有什么区别?#

jsp 代表的前台页面,servlet 是服务端和浏览器的中间层,运行时 jsp 被 web 容器(tomcat)编译成 servlet 了。

jsp 有哪些内置对象?作用分别是什么?#

  • request 用户端请求,此请求会包含来自 GET/POST 请求的参数

  • response 网页传回用户端的回应

  • pageContext 网页的属性是在这里管理

  • session 与请求有关的会话期

  • application servlet 正在执行的内容

  • out 用来传送回应的输出

  • config servlet 的构架部件

  • page JSP 网页本身

  • exception 针对错误网页,未捕捉的例外

    说一下 jsp 的 4 种作用域?#

    名称作用域
    application所有应用程序有效
    session当前整个会话有效
    request当前请求有效
    page当前页面有效

一般来说,cookie 记录了 sessionid;session 服务器端,cookie 客户端

说一下 session 的工作原理?#

当服务器创建完 session 对象后,会把 session 对象的 id 以 cookie 形式返回给客户端。这样,当用户保持当前浏览器的情况下再去访问服务器时,会把 session 的 id 传给服务器,服务器根据 session 的 id 来为用户提供相应的服务

能,通过 url 传 sessionid 即可

spring mvc 和 struts 的区别是什么?#

如何避免 sql 注入?#

使用 PreparedStatement 用?做占位符,或者使用具名变量的方式。

什么是 XSS 攻击,如何避免?#

什么是 CSRF 攻击,如何避免?#

七、异常#

throw 和 throws 的区别?#

throws 是方法后面的,表示这个方法可能抛出异常,在调用这个方法的时候就要 try catch 或者抛出异常,throw 是方法内用的 一般在 catch 里写。

final、finally、finalize 有什么区别?#

final 形容方法就是不可重写,形容类不可继承,形容变量就是常量。
finally 是 try catch 后面的
finalize () 是 object 中的一个方法,当 jvm 判断一个对象死亡的时候掉他做最后挣扎 (比如重写了这个方法把它重新引导 gc roots 上 GC 算法就不会回收它了)

try-catch-finally 中哪个部分可以省略?#

catch 和 finally 省略一个。

try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?#

会执行,会在 return 表达式之后执行。对其做改变的话也不变了。

常见的异常类有哪些?#

Error,runtime Exception,Exception 和 throw

八、网络#

http 响应码 301 和 302 代表的是什么?有什么区别?#

301 redirect: 301 代表永久性转移(Permanently Moved)

302 redirect: 302 代表暂时性转移(Temporarily Moved )

forward 和 redirect 的区别?#

这位小哥讲的贼好

简述 tcp 和 udp 的区别?#

TCP:面向连接的,可靠的,也就是不会丢失不会重复,按顺序。三次握手。面向字节的
UDP:面向无连接,不可靠的。面向报文的。但是快,可以广播

tcp 为什么要三次握手,两次不行吗?为什么?#

不行,两次只能保证单向连接是通畅的,不能保证双向都通。

说一下 tcp 粘包是怎么产生的?#

应用程读取缓存中的数据包的速度小于接收数据包的速度,缓存中的多个数据包会被应用程序当成一个包一次读取。

OSI 的七层模型都有哪些?#

应用层
表示层
会话层
传输层
网络层
数据链路层
物理层

get 和 post 请求有哪些区别?#

get 是从服务器上获取数据,post 是向服务器传送数据。

如何实现跨域?#

说一下 JSONP 实现原理?#

九、设计模式#

说一下你熟悉的设计模式?#

抽象工厂模式

简单工厂和抽象工厂有什么区别?#

简单工厂处理复杂度较小的对象,抽象工厂处理复杂度较大的;
简单工厂模式就是 实际的工厂 - 抽象类 - 实现不同的产品
抽象工厂就是 抽象工厂 - 不同的工厂 (实现不同产品族的产品)- 不同的产品(继承于产品的抽象类)

十、Spring/Spring MVC#

为什么要使用 spring?#

降低开发复杂度,方便集成其他框架,Mybatis,Hibernate,避免重复造轮子,专注于业务逻辑
支持 AOP,面向切面编程,把一些日志啊,事物啊,安全等等和业务逻辑没关的但是横跨多个业务的组件单独分离出来行程可重复使用的组件

解释一下什么是 aop?#

AOP 即 Aspect Oriented Program 面向切面编程
首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。
所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务
所谓的周边功能,比如性能统计,日志,事务管理等等
周边功能在 Spring 的面向切面编程 AOP 思想里,即被定义为切面
在面向切面编程 AOP 的思想里面,核心业务功能和切面功能分别独立进行开发
然后把切面功能和核心业务功能 “编织” 在一起,这就叫 AOP

解释一下什么是 ioc?#

控制翻转
简单说就是创建对象由以前的程序员自己 new 构造方法来调用,变成了交由 Spring 创建对象

spring 有哪些主要模块?#

1.Spring Core
框架的最基础的部分,提供 IOC 容器,对 bean 进行管理
2.Spring Context
基于 bean,提供上下文信息,扩展 JNDI,EJB, 电子邮件,国际化,校验和调度等功能
3.Spring DAO
提供 JDBC 的抽象层,它可消除冗余的 JDBC 编码和解析数据库厂商特有的错误代码,还提供了声明性事物的管理方法。
4.Spring ORM
提供了 对象 / 关系 映射 APIs 的集成层。其中包括 JPA,JDO,Hibernate,MyBatis 等。
5.Spring AOP
提供了符合 AOP Alliance 规范的面向方面的编程实现
6.Spring Web
提供了基础的 Web 开发的上下文信息,可与其他的 web 进行集成。
7.Spring MVC
提供了 Web 应用的 Model-View-Controller 全功能实现。

spring 常用的注入方式有哪些?#

构造方法注入,
setter 注入
注解注入

spring 中的 bean 是线程安全的吗?#

容器本身没有提供线程安全的策略,也就是不具备线程安全特性,要结合具体的 scope 的 Bean 去分析。
(bean 的作用域 scope:singleton、prototype,request、session、global session)
原型模式 prototype:每次创建一个新对象,各个线程用各个儿的,没有共享自然没有线程安全问题。
单例模式 singleton:如果是一个无状态的 bean,也就是说调用这个 bean 不会改变状态(字段属性),那么就是安全的。只有方法本身,对于有状态的 bean 最简单的改为原型模式即可。
Spring 创建的 bean 默认是 singleton 的,线程调用某个 bean 时,是持有一个 bean 对象的副本在自己的空间中,因为代码执行的速度很快,所以栈帧的生存时间很短,瞬间生灭。所以局部变量无法被外部使用。当你调用这个 bean 对象的全局变量时,就会出现线程安全问题了 (这时候你需要把 bean 定义为 prototype 了)!

spring 支持几种 bean 的作用域?#

  • singleton 模式:单例模式,在整个 Spring ioc 容器中,使用 singleton 定义的 bean 只有一个实例

  • prototype:原型模式,每次通过容器的 getbean 方法获取的 prototype 定义的 bean 时都产生一个新的实例

  • 只有在 web 应用中使用 Spring 时,request,session,global-session 作用域才有效 *

  • request:对于每次 HTTP 请求,使用 request 定义的 bean 都将产生一个实例,即每次 HTTP 请求都会产生不同的 bean 实例

  • session:同一个 Session 共享一个 bean 实例

  • global-session:同 session 作用域不同的是,所有的 session 共享一个实例

    spring 自动装配 bean 有哪些方式?#

    spring 配置文件中 节点的 autowire 参数可以控制 bean 自动装配的方式

  • default - 默认的方式和 “no” 方式一样

  • no:默认方式,手动装配方式,需要通过 设定 bean 的依赖关系

  • byName:根据 bean 的名字进行装配,当一个 bean 的名称和其他 bean 的属性一致,则自动装配

  • byType:根据 bean 的类型进行装配,当一个 bean 的属性类型与其他 bean 的属性的数据类型一致,则自动装配

  • constructor:根据构造器进行装配,与 byType 类似,如果 bean 的构造器有与其他 bean 类型相同的属性,则进行自动装配

  • autodetect:如果有默认构造器,则以 constructor 方式进行装配,否则以 byType 方式进行装配

    spring 事务实现方式有哪些?#

    (1)编程式事务管理对基于 POJO 的应用来说是唯一选择。我们需要在代码中调用 beginTransaction ()、commit ()、rollback () 等事务管理相关的方法,这就是编程式事务管理。
    (2)基于 TransactionProxyFactoryBean 的声明式事务管理
    (3)基于 @Transactional 的声明式事务管理
    (4)基于 Aspectj AOP 配置事务

    说一下 spring 的事务隔离?#

    读未提交;
    读提交;
    可重复读;
    序列化;

    说一下 spring mvc 运行流程?#

  1. 用户发送请求至前端控制器 DispatcherServlet
    2.DispatcherServlet 收到请求调用处理器映射器 HandlerMapping。
  2. 处理器映射器根据请求 url 找到具体的处理器,生成处理器执行链 HandlerExecutionChain (包括处理器对象和处理器拦截器) 一并返回给 DispatcherServlet。
    4.DispatcherServlet 根据处理器 Handler 获取处理器适配器 HandlerAdapter 执行 HandlerAdapter 处理一系列的操作,如:参数封装,数据格式转换,数据验证等操作
  3. 执行处理器 Handler (Controller,也叫页面控制器)。
    6.Handler 执行完成返回 ModelAndView
    7.HandlerAdapter 将 Handler 执行结果 ModelAndView 返回到 DispatcherServlet
    8.DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器
    9.ViewReslover 解析后返回具体 View
    10.DispatcherServlet 对 View 进行渲染视图(即将模型数据 model 填充至视图中)。
    11.DispatcherServlet 响应用户。

自我理解可以描述一下从 V 到 C 到 M 到 C 再到 V 的过程

spring mvc 有哪些组件?#

前端控制器 DispatcherServlet
处理器映射器 HanderMapping
处理器适配器 HaderAdapter
视图解析器 ViewResolver
异常处理器 HandlerExceptionResolver
视图组件 View

@RequestMapping 的作用是什么?#

是一个用来处理请求地址映射的注解,可用于类或者方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

@Autowired 的作用是什么?#

自动装配注解:它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作

十一、Spring Boot/Spring Cloud#

什么是 spring boot?#

“springboot 就是 Spring 开源框架下的子项目,是 Spring 的一站式解决方案,主要是简化了 spring 的使用难度,降低了对配置文件的要求,使得开发人员能够更容易得上手。”

spring boot 就是一个大框架里面包含了许许多多的东西,其中 spring 就是最核心的内容之一

为什么要用 spring boot?#

简化 Spring 的使用难度。集和各种框架,WEB 容器等

spring boot 核心配置文件是什么?#

application.properties&&bootstrap.properties
application.yml&&bootstrap.yml
bootstrap 配置文件是系统级别的,用来加载外部配置,如配置中心的配置信息,也可以用来定义系统不会变化的属性. bootstatp 文件的加载先于 application 文件
application 配置文件是应用级别的,是当前应用的配置文件
properties 是 key=value,bootstrap 是 key

spring boot 配置文件有哪几种类型?它们有什么区别?#

上个问题

spring boot 有哪些方式可以实现热部署?#

使用调试模式 Debug 实现热部署
spring-boot-devtools
Spring Loaded
JRebel

jpa 和 hibernate 有什么区别?#

Hibernate ORM 是 JPA 规范的一个实现
Java Persistence API
JPA 是一个 Java 编程语言接口规范,它描述了使用标准 JAVA 平台和 JAVA 企业版本的关系型数据的管理。JPA API 是 JAVA 社区专家组关于 JSR220 的一部分,JPA2.0 是 JSR317 专家组的工作。

什么是 spring cloud?#

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry.
根据 Spring Cloud 的官方网站,Spring Cloud 为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,领导选举,分布式会话,集群状态)分布式系统间的协作产生了一些样板性质的模式,开发者使用 Spring Cloud 就可以快速地构建基于这些模式的服务和应用。。

spring cloud 断路器的作用是什么?#

当一个服务调用另一个服务由于网络原因或者自身原因出现问题时 调用者就会等待被调用者的响应 当更多的服务请求到这些资源时
导致更多的请求等待 这样就会发生连锁效应(雪崩效应) 断路器就是解决这一问题。

spring cloud 的核心组件有哪些?#

  • 服务发现 ——Netflix Eureka

    一个 RESTful 服务,用来定位运行在 AWS 地区(Region)中的中间层服务。由两个组件组成:Eureka 服务器和 Eureka 客户端。Eureka 服务器用作服务注册服务器。Eureka 客户端是一个 java 客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix 在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。

  • 客服端负载均衡 ——Netflix Ribbon

    Ribbon 客户端组件提供一系列完善的配置选项,比如连接超时、重试、重试算法等。Ribbon 内置可插拔、可定制的负载均衡组件。

  • 断路器 ——Netflix Hystrix

    断路器可以防止一个应用程序多次试图执行一个操作,即很可能失败,允许它继续而不等待故障恢复或者浪费 CPU 周期,而它确定该故障是持久的。断路器模式也使应用程序能够检测故障是否已经解决。如果问题似乎已经得到纠正​​,应用程序可以尝试调用操作

  • 服务网关 ——Netflix Zuul
    微服务网关,这个组件是负责网络路由的。

  • Feign

    基于 fegin 的动态代理机制,根据注解和选择机器,拼接 Url 地址,发起请求,Feign 是一个声明性的 Web 服务客户端。它使编写 Web 服务客户端变得更容易。feigin 是一种模板化,声明式的 http 客户端,feign 可以通过注解绑定到接口上来简化 Http 请求访问。与当我们访问别的服务端口的时候 大部分使用 httpclient 等请求进行调用不同,在 eureka 注册的服务,我们可以使用 Feign 声明接口的形式来进行相关服务的调用,并提供了失败回退(其实是 Hystrix 组件的使用)。Feign 只是一个便利的 rest 框架,简化调用,最后还是通过 ribbon 在注册服务器中找到服务实例,然后对请求进行分配。

    十二、Hibernate#

    为什么要使用 hibernate?#

    全自动 orm 框架

    什么是 ORM 框架?#

    对象关系映射,将数据库和代码的实例联系起来

    hibernate 中如何在控制台查看打印的 sql 语句?#

    hibernate 有几种查询方式?#

    hibernate 实体类可以被定义为 final 吗?#

    在 hibernate 中使用 Integer 和 int 做映射有什么区别?#

    hibernate 是如何工作的?#

    get () 和 load () 的区别?#

    说一下 hibernate 的缓存机制?#

    hibernate 对象有哪些状态?#

    在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?#

    hibernate 实体类必须要有无参构造函数吗?为什么?#

    十三、Mybatis#

    半自动 orm 框架

    mybatis 中 #{} 和 ${} 的区别是什么?#

    #{} 代表的是占位符?调用 PreparedStatement 的 set 方法来赋值。
    ${} 字符串替换,就是把 ${} 替换成变量的值。
    使用 #{} 可以有效的避免 sql 注入,提高系统安全性,原因在于:预编译机制,预编译完成之后,SQL 的结构已经固定,即便用户输入非法参数,也不会对 SQL 的结构产生影响,从而避免了潜在的安全风险

    mybatis 有几种分页方式?#

    mybatis 四种分页方式

  • 数组分页:查询出所有放到 list 中然后截取 逻辑

  • sql 分页:limit (); 物理

  • 拦截器分页:实现一个拦截器 物理

  • RowBounds 分页:数据量小的时候 ;逻辑

    RowBounds 是一次性查询全部结果吗?为什么?#

    表面上是查出所有,但其实是分次查询出所有,基于 jdbc 进行的封装,jdbc 驱动有个参数是 Fetch Size 配置,要查更多的话就调用了 next ();

    mybatis 逻辑分页和物理分页的区别是什么?#

    逻辑分页就是查出所有,然后在结果中分割分页数据;
    物理分页就是查出来就是分好页的。

    mybatis 是否支持延迟加载?延迟加载的原理是什么?#

    支持延迟加载,设置 lazyloadingEnable=true 即可开启。
    延迟加载的原理的是调用的时候触发加载,而不是在初始化的时候就加载信息。 先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能。

    说一下 mybatis 的一级缓存和二级缓存?#

  • 一级缓存:基于 PerpetualCache 的 HashMap 本地缓存,他的生命周期和 sqlsesiion 一致,有多个 session 或者分布式环境中操作数据可能会有脏数据,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认一级缓存是开启的。

  • 二级缓存:也是基于基于 PerpetualCache 的 HashMap 本地缓存,不同之处在于其存储作用域为 Mapper 级别的,如果多个 sqlsession 要共用缓存就要开启二级缓存。

  • 缓存更新机制:当一个作用域 进行了 CUD 操作后,那么默认作用域下的 select 都被 clear。

    mybatis 和 hibernate 的区别有哪些?#

    半 orm 和 完全 orm 框架。
    mybatis 自己写 sql 比较灵活,但是移植性差。 hibernate 可以用第三方的二级缓存。

    mybatis 有哪些执行器(Executor)?#

  • SimpleExecutor:每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭 Statement 对象。

  • ReuseExecutor:执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map 内,供下一次使用。简言之,就是重复使用 Statement 对象。

  • BatchExecutor:批量执行器

mybatis 分页插件的实现原理是什么?#

(分页插件 PageHelper 原理)[https://www.cnblogs.com/dengpengbo/p/10579631.html]

mybatis 如何编写一个自定义插件?#

MyBatis 自定义插件针对 MyBatis 四大对象(Executor,StatementHandler,ParamentHandler,ResultSetHandler)进行拦截。MyBatis 插件要实现 Interceptor 接口

十四、RabbitMQ#

十五、Kafka#

kafka 可以脱离 zookeeper 单独使用吗?为什么?#

不能,应为 kafka 需要 zookeeper 管理协调 kafka 的节点服务器,kafka 就是基于 zookeeper 协调的分布式消息系统。

kafka 有几种数据保留的策略?#

两种,按照过期时间保留(默认为 7 天)和按照存储的消息大小(1073741824)保留。

kafka 同时设置了 7 天和 10G 清除数据,到第五天的时候消息达到了 10G,这个时候 kafka 将如何处理?#

执行清除数据,无论哪个条件满足,都会清除数据

什么情况会导致 kafka 运行变慢?#

CPU, 性能瓶颈,磁盘读写瓶颈,网络瓶颈。

使用 kafka 集群需要注意什么?#

集群的数量不是越多越好,最好不要超过 7 个,因为节点越多,消息复制需要的时间就越长,整个群组的吞吐量就越低。 集群数量最好是单数,因为超过一半故障集群就不能用了,设置为单数容错率更高。

kafka 如何保证数据不丢失#

kafka 可以保证分区消息的顺序,同一个分区,先发送到 kafka 分区的消息,会被先消费掉。
kafka 是通过一个集群对外提供服务,只要是集群中多个副本中有一个副本是活跃的,那么收到的消息就不会丢失。
主要需要保证三个地方数据不丢失

  • 保证生产者数据不丢失
    kafka 的 acks 机制,生产者客户端设置 acks 参数为 0,1,all。0 代表生产者发出去就算成功了。1 代表 Partition leader 写成功就成功了,设置为 all 的话就是还要要求 ISR 里和 leader 保持同步的那些 partiation 也要写成功才可以。

  • 集群中 broker 数据不丢失
    topic 按照 partition 分为不同数据(partition 0 ,partition 1)放在不同的 broker 上,这样就保证了 topic 数据是分布式存储的,对于每一个 partition 都有相应的副本,其中有的是 partition 0 leader,partition 0 follower。显而易见的是副本的数量不能超过 broker 的数量。 如果 leader 挂了,选一个 follower 当 leader。其中和 leader 保持同步的是 ISR,不保持同步的是 OSR, AR=ISR+OSR;

  • 消费者数据不丢失
    通过 offset commit 机制来保证,kafka 自己记录了每次消费的 offset 数值,下次继续消费的时候,会接着上次的 offset 进行消费。

    消费者消费过程#

    同一个消费者组的消费者可以消费同一个 topic 下不同的分区,但是同一个组内的消费者不能消费同一个分区,所以建议消费者组的 consumer 的数量与 partition 的数量一致!

    为什么要使用 KafKa,消息队列的作用是什么?#

  • 削峰:用户请求过大的话,服务器可能受不了。先存入消息队列,然后慢慢处理。

  • 解耦和扩展性:让不同的系统间解耦,方便进行扩展。解决不同系统间耦合度过大的问题

  • 冗余:一对多的方式,一个生产者发布消息,可以被多个订阅 topic 的服务消费到,供多个毫无关联的业务使用。

  • 异步通信:客户端 A,客户端 B,客户端 N 订阅同一主题,进行消息发布和接收。实现类似聊天室效果。

    KafKa 配置参数详解#

    KafKa 配置参数大详解

    十六、Zookeeper#

    Zookeeper 是什么#

    ZooKeeper 是一个开放源码的分布式协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

    zookeeper 都有哪些功能?#

    zookeeper = 文件系统 + 通知机制

  • 文件系统
    zookeeper 可以为客户端管理状态信息,虽然存储的数量较小(每个节点默认不可超过 1M)

  • 通知机制
    可以为客户端监听指定数据节点的状态,并在数据节点发生改变时,通知客户端

    zookeeper 有几种部署模式?#

    部署模式:单机模式、伪集群模式、集群模式。

    zookeeper 怎么保证主从节点的状态同步?#

    zookeeper 的核心是原子广播,这个机制保证了各个 server 之间的同步。实现这个机制的协议叫 zab 协议,zab 协议有两种模式,分别是恢复模式(选主)和广播模式(同步)。当服务启动或者领导者崩溃后,zab 进入了恢复模式,当领导者被选举出来,且大多是 server 完成了和 leader 的状态同步以后,恢复模式就结束了。状态同步保证了 leader 和 server 具有相同的系统状态。

    集群中为什么要有主节点?#

    在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行。其他机器可以共享这个结果,这样可以大大减少重复计算,提高性能。所以就需要主节点。

    集群中有三台服务器,其中一个节点宕机,这个时候 zookeeper 还可以使用么?#

    可以,单数服务器不超过一半的服务器宕机就可以继续使用。

    说一下 zookeeper 的通知机制#

    客户端会对某个 znode 建立一个 watcher 事件,当 znode 发生变化时,这些客户端会收到 zookeeper 的通知,然后客户端可以根据 znode 变化来做出业务上的改变。

    十七、MySql#

    数据库的三范式是什么?#

    1NF: 字段不可再分
    2NF: 有主键,其他非主键字段依赖主键
    2NF: 非主键字段不互相依赖

    一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?#

    表的类型是 InnoDB 就是 6 ,自增表最大记录保存在内存中,重启就没了
    表的类型是 MylSAM 就是 8 ,最大记录保存在数据中,重启也还在(Myisam 不支持事务)

    如何获取当前数据库版本?#

    select version()
    cmd 中 mysql -v

    说一下 ACID 是什么?#

    A :原子性,事物不可分割,要不全完成,要不全不发生,不会停留在一个中间阶段,中间出错了就会回滚到开始前的状态
    C:Consistency: 一致性:数据库从一个一致的状态到另一个 一致的状态,数据完整性保持一致
    I:隔离性,多个事务之前不会受到影响
    D:持续性:事务结束后数据被永久的记录下来,系统故障也不会消失。

    char 和 varchar 的区别是什么?#

    char 是固定长度,申请的多少就是多少不够的补齐
    varchar 是可变长度,根据实际情况变化,实际长度 + 1 字节自己存储长度

    float 和 double 的区别是什么?#

    都是浮点数,单精度和双精度的区别

    mysql 的内连接、左连接、右连接有什么区别?#

    内连接就是 join,左连接是 left join,右;连接是 right join,有个图可以很好地表示这个,我去找一下。。。

    mysql 索引是怎么实现的?#

    B + 树,单独的一篇博客 MySQL 索引的学习

    怎么验证 mysql 的索引是否满足需求?#

    最左匹配原则,遇到范围后面的条件的索引就不会生效
    有 null 值得索引不生效

    说一下数据库的事务隔离?#

    读未提交:可以读到未提交的 这不有病么
    读提交:Oracle 数据库的默认隔离级别
    可重复度:针对不可重复度,普通查询即使快照查询。mysql 的默认隔离级别
    串行化:最牛逼的,事务串行化一个一个执行,啥都能避免但是效率奇差

为什么会出现 “脏读”?因为没有 “select” 操作没有规矩。
为什么会出现 “不可重复读”?因为 “update” 操作没有规矩。
为什么会出现 “幻读”?因为 “insert” 和 “delete” 操作没有规矩。
“读未提(Read Uncommitted)” 能预防啥?啥都预防不了。
“读提交(Read Committed)” 能预防啥?使用 “快照读(Snapshot Read)”,避免 “脏读”,但是可能出现 “不可重复读” 和 “幻读”。
“可重复读(Repeated Red)” 能预防啥?使用 “快照读(Snapshot Read)”,锁住被读取记录,避免出现 “脏读”、“不可重复读”,但是可能出现 “幻读”。
“串行化(Serializable)” 能预防啥?排排坐,吃果果,有效避免 “脏读”、“不可重复读”、“幻读”,不过效果谁用谁知道。

说一下 mysql 常用的引擎?#

InnoDB、MyIsam (不支持事务)
因为事务和行锁往往是我们之所以选择 InnoDB 表的理由

说一下 mysql 的行锁和表锁?#

表锁一般是 Myisam 使用的,开销小,加锁快,无死锁,并发度低
行锁一般是 InnoDB,开销大,加锁慢,会出现死锁,并发度高
只有通过索引条件检索数据,InnoDB 才会使用行级锁,否则,InnoDB 将使用表锁!

说一下乐观锁和悲观锁?#

乐观锁:version 来记录数据表中记录的版本
悲观锁:排它锁和共享锁

mysql 问题排查都有哪些手段?#

如何做 mysql 的性能优化?#

简历索引的方法对不对。查看性能

请你介绍一下 mysql 的 MVCC 机制#

MVCC 是一种多版本并发控制机制,是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现提交读和可重复读这两种隔离级别。MVCC 是通过保存数据在某个时间点的快照来实现该机制,其在每行记录后面保存两个隐藏的列,分别保存这个行的创建版本号和删除版本号,然后 Innodb 的 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回滚指针把一个数据行所有快照连接起来。

mysql 查询过程#


查询过程

十九、JVM#

说一下 jvm 的主要组成部分?及其作用?#

类加载器,执行引擎,本地接口,运行时数据区

说一下 jvm 运行时数据区?#

堆内存和栈内存,1.8 之前有方法区,栈还分为本地方法栈和虚拟机栈。程序计数器。

说一下堆栈的区别?#

栈放基本变量和引用分为各个栈帧,,堆放所有的实例化的对象,以数据的角度,分为对象头,实例数据和对象填充。
以 GC 的角度分为新生代和老年代。堆是所有线程共有,一个 jvm 实例进程一个。栈是每个线程都有一个。

队列和栈是什么?有什么区别?#

queue 和 stack 吃多了拉就是 queue,吃多了吐就是栈,java 中用 deque 来模仿 stack

什么是双亲委派模型?#

类加载器,把类加载到虚拟机的方法区的,而加载的规则就叫双亲委派机制(应用类加载器 -> 扩展类加载器 -> 启动类加载器,有的还有自定义类加载器。)
从上到下:
BootStarpClassloader:主要负责加载核心的类库 (java.lang.* 等),构造 ExtClassLoader 和 APPClassLoader。
ExtClassLoader:主要负责加载 jre/lib/ext 目录下的一些扩展的 jar。
AppClassLoader:主要负责加载应用程序的主函数类
这种设计有个好处是,如果有人想替换系统级别的类:String.java。篡改它的实现,但是在这种机制下这些系统的类已经被 Bootstrap classLoader 加载过了,所以并不会再去加载,从一定程度上防止了危险代码的植入。

说一下类加载的执行过程?#

开一篇博客单独学习吧

怎么判断对象是否可以被回收?#

是否继承与 root,不继承的统统 GC,两种方法,一种是引用计数法,一种是可达性分析算法。

java 中都有哪些引用类型?#

强软弱虚 && 队列 kanyixia

说一下 jvm 有哪些垃圾回收算法?#

ms (标记清除法),mc (标记压缩法)、复制法

说一下 jvm 有哪些垃圾回收器?#

  • Serial 收集器(复制算法):新生代单线程收集器,标记和清理都是单线程,优点是简单高效。是 client 级别默认的 GC 方式,可以通过 - XX:+UseSerialGC 来强制指定。

  • Serial Old 收集器 (标记 - 整理算法):老年代单线程收集器,Serial 收集器的老年代版本。

  • ParNew 收集器 (停止 - 复制算法) :新生代收集器,可以认为是 Serial 收集器的多线程版本,在多核 CPU 环境下有着比 Serial 更好的表现。

  • Parallel Scavenge 收集器 (停止 - 复制算法):并行收集器,追求高吞吐量,高效利用 CPU。吞吐量一般为 99%, 吞吐量 = 用户线程时间 /(用户线程时间 + GC 线程时间)。适合后台应用等对交互相应要求不高的场景。是 server 级别默认采用的 GC 方式,可用 - XX:+UseParallelGC 来强制指定,用 - XX=4 来指定线程数。

  • Parallel Old 收集器 (停止 - 复制算法):Parallel Scavenge 收集器的老年代版本,并行收集器,吞吐量优先。

  • CMS (Concurrent Mark Sweep) 收集器(标记 - 清理算法):高并发、低停顿,追求最短 GC 回收停顿时间,cpu 占用比较高,响应时间快,停顿时间短,多核 cpu 追求高响应时间的选择。

    详细介绍一下 CMS 垃圾回收器?#

    Here

    新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?#

    新生代回收器:Serial、ParNew、Parallel Scavenge
    老年代回收器:Serial Old、Parallel Old、CMS
    整堆回收器:G1
    新生代垃圾回收器一般采用的是复制算法,复制算法的优点是效率高,缺点是内存利用率低;老年代回收器一般采用的是标记 - 整理的算法进行垃圾回收。

    简述分代垃圾回收器是怎么工作的?#

    分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。 新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,
    它的执行流程如下:
    把 Eden + From Survivor 存活的对象放入 To Survivor 区;
    清空 Eden 和 From Survivor 分区; From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。
    每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代。
    老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的执行算法。
    以上这些循环往复就构成了整个分代垃圾回收的整体执行流程。

    说一下 jvm 调优的工具?#

  • 1.jps
    jps -q 只输出 pid
    jps -m 启动时 main () 的参数
    jps -l 输出主类全名
    jps -v 输出虚拟机进程启动时的参数

  • 2.jstat
    jstat -class LVMID 250 20 监视类装载卸载等信息
    jstat -gc LVMID 250 20 监视堆状况信息
    jstat -gccapacity LVMID 250 20 监视堆状况信息,主要是各个区域使用到的最大最小空间
    jstat -gcutil LVMID 250 20 监视堆状况信息,主要是已使用的百分比
    jstat -gccause LVMID 250 20 和 - gcutil 差不多,只不过会额外输出上一次 GC 产生的原因
    jstat -gcnew LVMID 250 20 监视新生代
    jstat -gcnewcapacity LVMID 250 20 监视堆状况信息,主要是新生代各个区域使用到的最大最小空间
    jstat -gcold LVMID 250 20 监视老年代
    jstat -gcoldcapacity LVMID 250 20 监视老年代,主要是各个区域使用到的最大最小空间
    jstat -compiler LVMID 250 20 JIT 编译过的方法
    jstat -printcompilation LVMID 250 20 JIT 编译过的方法

  • 3.jinfo
    jinfo LVMID 打印配置信息

  • 4.jmap (堆信息)
    jmap -dump,format=b,file=heap.bin 29494

  • 5.jhat (分析 jmap 生成的文件)
    jhat heap.bin
    http://localhost:7000/

  • 6.jstack
    jstack -F LVMID 打印线程信息
    jstack -l LVMID 除了堆栈外,显示关于锁的附加信息
    jstack -m LVMID 如果调用本地方法的话,可以显示 C/C++ 的堆栈

  • 7.jconsole
    JDK 自带 bin 目录下,这个工具很简单,随便点点就可以知道起功能了

  • 8.jvisualvm
    visualvm 功能比较强大,插件也比较多,值得好好研究。

    JVM 常用调试工具介绍

常用的 jvm 调优的参数都有哪些?#

这个比较全

二十、应用服务器优化技术#

分布式缓存#

缓存的本质就是内存中的哈希表 主要用来存放那些读写比很高、变化很少的数据,这样应用程序读取数据时先到缓存中读取,如果没有或者数据已经失效再去访问数据库或文件系统,并根据拟定的规则将数据写入缓存。
特点: 分布式缓存能够高性能地读取数据、能够动态地扩展缓存节点、能够自动发现和切换故障节点、能够自动均衡数据分区,而且能够为使用者提供图形化的管理界面,部署和维护都十分方便。

消息队列#

消息队列服务器,是位于应用服务器和数据库服务器之间的一个服务器。消息队列服务器作为一个缓冲,接收应用服务器发送过来的数据库操作命令,然后按照自己的配置,依次发送给数据库服务器来执行。这种数据库执行的方式,我们称之为异步写入数据库。
特点:由于消息队列服务器的速度远远高于数据库服务器,所以能够快递处理并返回数据。消息队列服务器具有更好的扩展性。在高并发的情况下,延迟写入数据库,可以有效降低数据库的压力。

使用集群#

在网站高并发访问的场景下,使用负载均衡技术为一个应用构建一个由多台服务器组成的服务器集群,将并发访问请求分发到多台服务器上处理,避免单一服务器因负载压力过大而响应缓慢,使用户请求具有更好的响应延迟特性。

二十一、jQuery#

parseJson 和 getJSON#

$.parseJson () 方法可以把 JSON 格式的字符串变成 JSON 对象,而 $.getJSON () 方法是向服务端发送请求获取 JSON 数据的。

二十二、Redis#

redis 是什么?都有哪些使用场景?#

REmote DIctionary Server 是一个高性能的 (key/value) 分布式内存数据库,基于内存运行并支持持久化的 NoSQL 数据库,是当前最热门的 NoSql 数据库之一,也被人们称为数据结构服务器。
缓存数据。比如查询工伤人员的列表。提高计算效率。

redis 有哪些功能?#

支持数据持久化,数据缓存功能,支持消息队列。

redis 为什么是单线程的?#

因为没必要多线程,纯内存操作
省去了线程的上下文切换,不用担心各种锁的问题
使用多路 I/O 复用模型,非阻塞 IO;// 这里 “多路” 指的是多个网络连接,“复用” 指的是复用同一个线程

Redis 持久化机制#

RDB DataBase (我自己乱拼的) 保存某时刻内存的快照数据。刚查了是 Redis Database Backup
AOF:Applend Only File 记录写入数据的日志。

Redis 数据类型#

Strings、Hashs、lists、sets、sorted sets、Bitmaps (按位操作的字符串)

为啥 Redis 单线程模型也能效率这么高?#

  • 纯内存操作

  • 非阻塞 IO 的多路复用机制

  • C 实现

  • 单线程避免了多线程的上下文切换操作

    Redis 操作#

  • Strings
    SET samwell redis
    GET samwell

  • Hash
    hset samwell id 666
    hset samwell name wang
    hmset samwell age “18” sex “男”
    hgetall samwell

  • List
    LPUSH samwell redis
    LPUSH samwell oracle
    LPUSH samwell mysql
    LRANGE samwell 0 3

  • Sets
    SADD samwell redis
    SADD samwell mysql
    SADD samwell mysql
    SMEMBERS samwell

  • Sorted set
    ZADD samwell 1 redis
    ZADD samwell 2 mysql
    ZADD samwell 2 oracle
    ZRANGE samwell 1 2 WITHSCORES

  • Redis 过期策略有哪些?
    定期删除 + 惰性删除
    所谓定期删除,指的是 Redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除。
    惰性删除指的是,当你获取一个 key 时这个 key 是否设置了过期时间,如果设置了过期时间并且已经过期,就直接删除

  • 内存淘汰机制
    如果上面的两个都没走,那过期的一些 key 还是会占着内存,那么就会走内存淘汰机制
    常用的内存淘汰机制就是
    allkeys-lru:当内存不足容纳新数据,在键空间中移除最近最少使用的 key。
    其他的内存淘汰机制如下:
    allkeys-random:随机删除
    volatile-lru:在设置了过期时间的键空间中删除最少使用。
    volatile-randow: 在设置了过期时间的键空间中随机删
    volatile-ttl:在设置里过期时间的键空间中,删除过期时间最早的

  • Redis 如何实现高并发和高可用
    高并发:主从机制,一主多从,主用来写,从用来读,读写分离。可以很轻松的进行水平扩容。进而支持读的高并发
    高可用:基于哨兵实现高可用 ,当 master 宕机了 其他的 slave 会选举成为 master

    redis 支持的 java 客户端都有哪些?#

    jedis && Redisson

    怎么保证缓存和数据库数据的一致性?#

    读的时候先读缓存,缓存没有读数据库。然后放到缓存里
    写的时候,先写数据库,然后删除缓存。// 先删缓存,再改数据库
    更新的时候 数据唯一标识,读数据的时候也是先读数据库再更新缓存,和之前的改数据库操作放到 jvm 队列中,确保更新完了再读。如果等的时间过长,可以直接读旧的数据。

或者终极大招,一致性越高,失效期越短。定期删除

redis 如何实现分布式锁#

//获取锁(unique_value可以是UUID等)
SET resource_name unique_value NX PX  30000

//释放锁(lua脚本中,一定要比较value,防止误解锁)
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

redis 如何做内存优化?#

redis 淘汰策略有哪些?#

allkeys-lru
allkeys-random
volital-lru

redis 常见的性能问题有哪些?该如何解决?#

目前只知道持久化会影响 redis 性能,

Master 最好不要做任何持久化工作,如 RDB 内存快照和 AOF 日志文件
如果数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一次
为了主从复制的速度和连接的稳定性,Master 和 Slave 最好在同一个局域网内
尽量避免在压力很大的主库上增加从库

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。