1.Java快排。

public static void quickSort(int[] num,int begin,int end){
    	if(begin<end){
    		int number =num[begin];
    		int a=begin;
    		int b=end;
    		while(a!=b){
    			while(a<b&&number<num[b]) {
    				b--;
    			}
    			if(a<b){
    					num[a]=num[b];
    					a++;
    				}
    			
    			while(a<b&&number>num[a]) {
    				a++;
    			}
    			if(a<b){
    					num[b]=num[a];
    					b--;
    				}
    		}
    		num[a]=number;
    		quickSort(num,begin,a-1);
    		quickSort(num,a+1,end);
    	}

2.你使用的Java JDK版本,该版本有哪些GC,其运行机制是怎样的?
2.1 使用的是jdk1.8版本,垃圾回收(Garbage Collection,简称GC)可以自动清空堆中不再使用的对象。
2.2 Java的垃圾回收机制是JVM对内存空间(对象)的管理方式
java开发人员无法使用指针自由的进行内存管理,而GC让他们摆脱繁琐的内存管理工作,让开发更有效率
Java堆是被所有线程共享的一块内存区域,所有对象实例和数组都在堆上进行内存分配。为了进行高效的垃圾回收,JVM把堆内存分为新生代、老年代和永久代3个区域

  • 新生代分为Eden区和Survivor区,大多数情况下,对象在Eden中分配,当Eden没有足够空间时,会被触发一次Minor GC,Survivor区是幸存者区,是新生代和老年代的缓冲区域(当新生代发生GC(Minor GC)时,会将存活的对象移动到S0内存区域,并清空Eden区域,当再次发生Minor GC时,将Eden和S0中存活的对象移动到S1内存区域。)存活对象反复在S0和S1之间移动,每次进行GC,对象的GC年龄相应的+1,当超过默认值15时,会被移动到年老代。
  • 老年代:用于存放经过几次MInor GC之后依旧存活的对象,当老年代的空间不足时,会触发Major GC/Full GC,速度一般比Minor GC慢10倍以上
  • 永久代:在JDK8之前的HotSpot实现中,类的元数据如方法数据、方法信息(字节码,栈和变量大小)、运行时常量池、已确定的符号引用和虚方法表等被保存在永久代中
    虚拟机团队在JDK8的HotSpot中,把永久代从Java堆中移除了,并把类的元数据直接保存在本地内存区域(堆外内存),称之为元空间。(好处:永久代的调优过程非常困难,永久代的大小很难确定,其中涉及到太多因素,如类的总数、常量池大小和方法数量等,而且永久代的数据可能会随着每一次Full GC而发生移动。 而在JDK8中,类的元数据保存在本地内存中,元空间的最大可分配空间就是系统可用内存空间,可以避免永久代的内存溢出问题,不过需要监控内存的消耗情况,一旦发生内存泄漏,会占用大量的本地内存。
    JDK7之前的HotSpot,字符串常量池的字符串被存储在永久代中,因此可能导致一系列的性能问题和内存溢出错误。在JDK8中,字符串常量池中只保存字符串的引用。)
    在 JDK 1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域(永久代使用的是JVM的堆内存空间,而元空间使用的是物理内存,直接受到本机的物理内存限制)。

2.3 回收的步骤有2步:

  • .查找内存中不再使用的对象(引用计数法、可达性分析法【根搜索法】)
    引用计数法:在对象上添加一个引用计数器,每当有一个对象引用它时,计数器加1,当使用完该对象时,计数器减1,计数器值为0的对象表示不可能再被使用。
    引用计数法实现简单,判定高效,但不能解决对象之间相互引用的问题。
    可达性分析:通过一系列称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,搜索路径称为 “引用链”,以下对象可作为GC Roots:
本地变量表中引用的对象
	方法区中静态变量引用的对象
	方法区中常量引用的对象
	Native方法引用的对象

当一个对象到 GC Roots 没有任何引用链时,意味着该对象可以被回收。

  • 释放这些对象占用的内存(垃圾回收算法:标记-清除、复制和标记-整理)
    标记-清除:对待回收的对象进行标记。
    算法缺点:效率问题,标记和清除过程效率都很低;空间问题,收集之后会产生大量的内存碎片,不利于大对象的分配。
    复制:复制算法将可用内存划分成大小相等的两块A和B,每次只使用其中一块,当A的内存用完了,就把存活的对象复制到B,并清空A的内存,不仅提高了标记的效率,因为只需要标记存活的对象,同时也避免了内存碎片的问题,代价是可用内存缩小为原来的一半。
    标记-整理:在老年代中,对象存活率较高,复制算法的效率很低。在标记-整理算法中,标记出所有存活的对象,并移动到一端,然后直接清理边界以外的内存。

2.4 垃圾收集器

javaee简答题 java简答题及答案_老年代


上图展示了7种不同分代的收集器,如果两两之间存在连线,说明可以组合使用。

1、Serial收集器(串行GC)

Serial 是一个采用单个线程并基于复制算法工作在新生代的收集器,进行垃圾收集时,必须暂停其他所有的工作线程。对于单CPU环境来说,Serial由于没有线程交互的开销,可以很高效的进行垃圾收集动作,是Client模式下新生代默认的收集器。

2、ParNew收集器(并行GC)
ParNew其实是serial的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为与Serial一样。

3、Parallel Scavenge收集器(并行回收GC)
Parallel Scavenge是一个采用多线程基于复制算法并工作在新生代的收集器,其关注点在于达到一个可控的吞吐量,经常被称为“吞吐量优先”的收集器。

吞吐量 = 用户代码运行时间 /(用户代码运行时间 + 垃圾收集时间)

Parallel Scavenge提供了两个参数用于精确控制吞吐量:

-XX:MaxGCPauseMillis 设置垃圾收集的最大停顿时间
-XX:GCTimeRatio 设置吞吐量大小

4、Serial Old收集器(串行GC)
Serial Old 是一个采用单线程基于标记-整理算法并工作在老年代的收集器,是Client模式下老年代默认的收集器。

5、Parallel Old收集器(并行GC)
Parallel Old是一个采用多线程基于标记-整理算法并工作在老年代的收集器。在注重吞吐量以及CPU资源敏感的场合,可以优先考虑Parallel Scavenge和Parallel Old的收集器组合。

6、CMS收集器(并发GC)
CMS(Concurrent Mark Sweep)是一种以获取最短回收停顿时间为目标的收集器,工作在老年代,基于“标记-清除”算法实现,整个过程分为以下4步:
初始标记:这个过程只是标记以下GC Roots能够直接关联的对象,但是仍然会Stop The World;
并发标记:进行GC Roots Tracing的过程,可以和用户线程一起工作。
重新标记:用于修正并发标记期间由于用户程序继续运行而导致标记产生变动的那部分记录,这个过程会暂停所有线程,但其停顿时间远比并发标记的时间短;
并发清理:可以和用户线程一起工作。

CMS收集器的缺点:
对CPU资源比较敏感,在并发阶段,虽然不会导致用户线程停顿,但是会占用一部分线程资源,降低系统的总吞吐量。
无法处理浮动垃圾,在并发清理阶段,用户线程的运行依然会产生新的垃圾对象,这部分垃圾只能在下一次GC时收集。
CMS是基于标记-清除算法实现的,意味着收集结束后会造成大量的内存碎片,可能导致出现老年代剩余空间很大,却无法找到足够大的连续空间分配当前对象,不得不提前触发一次Full GC。

7、G1收集器
G1(Garbage First)是JDK1.7提供的一个工作在新生代和老年代的收集器,基于“标记-整理”算法实现,在收集结束后可以避免内存碎片问题。

G1优点:
并行与并发:充分利用多CPU来缩短Stop The World的停顿时间;
分代收集:不需要其他收集配合就可以管理整个Java堆,采用不同的方式处理新建的对象、已经存活一段时间和经历过多次GC的对象获取更好的收集效果;
空间整合:与CMS的”标记-清除”算法不同,G1在运行期间不会产生内存空间碎片,有利于应用的长时间运行,且分配大对象时,不会导致由于无法申请到足够大的连续内存而提前触发一次Full GC;
停顿预测:G1中可以建立可预测的停顿时间模型,能让使用者明确指定在M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。

使用G1收集器时,Java堆的内存布局与其他收集器有很大区别,整个Java堆会被划分为多个大小相等的独立区域Region,新生代和老年代不再是物理隔离了,都是一部分Region(不需要连续)的集合。G1会跟踪各个Region的垃圾收集情况(回收空间大小和回收消耗的时间),维护一个优先列表,根据允许的收集时间,优先回收价值最大的Region,避免在整个Java堆上进行全区域的垃圾回收,确保了G1收集器可以在有限的时间内尽可能收集更多的垃圾。

https://www.jianshu.com/p/5340978210cf 3.JDK同步机制是怎样?
https://www.jianshu.com/p/62d56eb0f8a2 4.说说你对面向对象编程的理解。

5.你知道的设计模式有哪些,分别应用于那些场景。

6.给出一段Java代码,问这段代码执行会发生什么?(我觉得用经过什么步骤会更加明确)
7.SQL基础,给出一个表,问怎样查询其中的某些内容。
8.数据库中键的数据结构是?
主键索引
唯一索引
【①.主键是一种约束,唯一索引是一种索引;
②.一张表只能有一个主键,但可以创建多个唯一索引;
③.主键创建后一定包含一个唯一索引,唯一索引并一定是主键;
④.主键不能为null,唯一索引可以为null;
⑤.主键可以做为外键,唯一索引不行;】
聚簇索引
数据库索引是通过B树和变形的B+树实现的。