Java基础

一.谈谈你对Java平台的理解?

Java是一种面向对象语言,最显著的特征有两个方面。一是“一次编译,到处执行”,能够非常容易地获得跨平台能力;另外就是垃圾回收,Java通过垃圾回收器回收分配内存,大多数情况下,程序员不需要自己关心内存的分配和回收。
我们日常会接触到JRE(Java Runtime Environment)或者JDK(Java Development Kit)。JRE,也就是Java运行环境,包含了JVM和Java类库,以及一些模块等。而JDK可以看做是JRE的一个超集,提供了更多工具,比如编译器、各种诊断工具等。
Java是解释执行的说法不太准确。我们开发的Java源代码(.java),首先通过Javac编译成字节码(.class),然后,在运行时,通过Java虚拟机内嵌的解释器将字节码转换成最终的机器码。但是常见的JVM,比如我们大多数情况使用的Oracle JDK提供的Hotspot JVM,都提供了JIT(Just-In-Time)编译器,也就是通常所说的动态编译器,JIT能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行了。在这里插入图片描述

test

Java平台知识图谱

二.Exception和Error有什么区别?

在这里插入图片描述

Java中的异常层次结构
Java语言规范中将派生于Error类或RuntimeException类的所有异常都称为非受查异常,所有其他的异常称为受查异常。 在程序中用try-catch块能够捕获的都是受查异常。 Exception和Error的不同之处:
Exception
1.可以是被控制(checked)或不可被控制的(unchecked)
2.表示一个由程序员导致的错误
3.应该由应用程序级被处理
Error:
1.总是不可控制的(unchecked)
2经常用来表示系统错误或低层资源的错误
3.如果可能的话,应该在系统级被捕捉

三、谈谈final、finally、finalize有什么不同?

1.final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值
2.finally一般作用于try-catch-finally代码块中,在处理异常的时候,通常我们将一定要执行的代码放在finally代码块中,表示不管是否出现异常,该代码块都会执行
3.finalize是一个方法,属于Object类的一个方法、而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用System的GC()方法时,有垃圾回收器调用finalize()方法,回收垃圾

四、强引用、软引用、弱引用、幻象引用有什么区别?

五、String、StringBuffer、StringBuilder有什么区别?

这三个类之间的区别主要在两个方面,即线程安全和运行速度两方面
1.这三个类之间的关系(都是通过字符数组来实现的)
StringBuffer类部分源码

public final class StringBuffer
      extends AbstractStringBuilder
      implements java.io.Serializable,CharSqeuence

StringBuilder类部分源码

public final class StringBuilder
     extends AbstractStringBuilder
     implements java.io.Serializable,CharSequence

String类部分源码

public final class String
      implements java.io.Serializable,Comparable<String>,CharSequence

这三个类的关系为:StringBuffer和StringBuilder都继承在AbstractStringBuilder这个类,而AbstractStringBuilder和String都继承自Object类(Object是所有Java类的超类)。这三个类之间的关系可以大致表示为:
在这里插入图片描述

2.String是不可变类,而StringBuffer、StringBuilder是可变类
    查看源码发现String类没有append()、delete()、insert()这三个成员方法,而StringBuffer和StringBuilder都有这些方法。
String--------字符串常量
StringBuffer----字符串变量
StringBuilder----字符串变量
3.执行速度
   在执行速度上,String<StringBuffer<StringBuilder
   3.1 String<StringBuffer
   这是因为String类是不可变的,即字符串常量,所有每次对String类型进行改变的时候其实都等于生产了一个新的String对象,然后将指针指向新的String对象。这就会对程序运行产生很大的影响,因为当内存中的无引用对象多了以后,JVM的GC进程就会进程垃圾回收,这个过程会消耗很长一段时间,因此经常改变内容的字符串最好不要用String类的对象。而如果使用StringBuffer类则结果就不一样了,每次结果都会对StringBuffer对象本身进行操作,而不是生成新的对象,在改变对象引用。在字符串经常改变的情况下推荐使用StringBuffer。
      但在某些特殊情况下,String对象的字符串拼接其实是被JVM解释成了StringBuffer对象的拼接,所以这些时候String对象的速度并不比StringBuffer对象慢。在下面的代码中,String运行速度远比StringBuffer块。

String string="This is only a"+"simple"+"test";
StringBuffer buffer=new StringBuffer("This is only a").append("simple").append("test");

但如果要拼接的字符串来自不同的String对象的话,结果就不一样了

String s1="This is only a";
String s2="simple";
String s3="test";
String string=s1+s2+s3;

这时候用StringBuffer速度更快
     3.2 StringBuffer<StringBuilder
      StringBuffer是同步的,使用了锁,产生了额外的开销;与没有同步的StringBuilder相比,速度要慢一些
4.线程安全与非线程安全
StringBuffer是线程安全的,而StringBuilder是非线程安全的
StringBuffer部分源代码

public synchronized int length(){
      return count;
 }
 
 @Override
 public synchronized void ensureCapacity(int minimumCapacity){
       super.ensureCapacity(minimunCapacity);
  }

@Override
public synchronized void trimToSize(){
      super.trimToSize();
 }

StringBuilder类的部分源码

@Override
   public StringBuilder append(int i){
         super.append(i);
         return this;
    }
@Override
  public StringBuilder insert(int index,char[] str,int offset,int len){
        super.insert(index,str,offset,len);
        return this;
   }
@Override
   public StringBuilder insert(int offset,Object obj){
          super.insert(offset,obj);
          return this;
    }

5.使用场景
String:使用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓存区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

六、动态代理是基于什么原理?

七、int和Integer有什么区别?

1.int与Integer的基本使用对比
(1)Integer是int的包装类;int是基本数据类型
(2)Integer变量必须实例化后才能使用;int变量不需要
(3)Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值
(4)Integer的默认值是null;int的默认值是0
2.int与Integer的深入对比
(1)由于Integer变量实际上是对一个Integer对象的引用,所以两个通过new生产的Integer变量永远是不相等的(因为new生产的是两个对象,其内存地址不同)

Integer i=new Integer(100);
Integer j=new Integer(100);
System.out.println(i==j);   //false

(2)Integer变量和int变量比较时,只要两个变量的值是相等的,则结果为true(因为包装类Integer和基本数据类型int比较时,Java会自动拆包为int,然后进行比较,实际上就是两个int变量的比较)

Integer i=new Integer(100);
int j=100;
System.out.println(i==j);      //true

Java两种数据类型
3.1Java两种数据类型分类
(1)基本数据类型,分为boolean、byte、int、char、long、short、double、float;
(2)引用数据类型,分为数组、类、接口
3.2 Java为每个原始类型提供了封装类
       为了编程的方便Java中引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer。

基本数据类型:boolean,char,byte,short,int,long,float,double
封装类类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

4 基本解析
4.1 自动装箱:将基本数据类型重新转换为对象

public class Test{
      public static void main(String[] args){
             //声明一个Integer对象
             Integer num=9;
             //以上的声明就是用到了自动装箱:解析为:Integer num=new Integer(9);
           }
  }

4.2 自动拆箱:将对象重新转换为基本数据类型

public class Test{
         public static void main(String[] args){
                //声明一个Integer对象
                Integer num=new Integer(9);

                //进行计算时隐含有自动拆箱
                System.out.println(num--);
              }
    }

八、对比Vector、ArrayList、LinkedList有何区别?

Vector,ArrayList,LinkedList都实现了java.util.list接口,但它们有不同的特征,具体表现在同步性和增删改的效率上。
1.同步性
ArrayList和LinkedList不是同步的,而Vector是同步的。如果不要求线程安全的话,可以使用ArrayList或LinkedList,可以节省为同步而消耗的开销。但在多线程的情况下,就需要使用Vector。
2.检索、插入、删除对象的效率
Vector和ArrayList作为动态数组,其内部元素以数组形式顺序存储,所以非常适合随机访问的场合。但其插入和删除的效率较低
LinkedList是基于链表的数据结构,插入和删除的效率很高,但是随机访问的性能则要比动态数组慢很多

十、如何保证集合是线程安全的?ConcurrentHashMap如何实现高效的线程安全?

十二、Java有几种文件拷贝方式?哪一种最高效?

十三、谈谈你知道的设计模式?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值