栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

20220507JAVASE1阶段试

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

20220507JAVASE1阶段试

一、单选题


1. 在异常处理中,以下描述不正确的有
A、 try块不可以省略
B、 可以使用多重catch块
C、 finally块可以省略
D、 catch块和finally块可以同时省略
参考答案:D        try不能单独使用,必须加catch和finally其中一个
2. 事务隔离级别是由谁实现的?
A、 Java应用程序
B、 Hibernate
C、 数据库系统
D、 JDBC驱动程序
参考答案:C        

3. 语句:char foo='中',是否正确?(假设源文件以GB2312编码存储,并且以javac – encoding GB2312命令编译)
A、 正确
B、 错误
参考答案:A

Java语言中,中文字符所占的字节数取决于字符的编码方式

一般情况下,采用ISO8859-1编码方式时,一个中文字符与一个英文字符一样只占1个字节;采用GB2312或GBK编码方式时,一个中文字符占2个字节;

而采用UTF-8编码方式时,一个中文字符会占3个字节。

java中,char和byte都是基础数据类型,其中的byte和C++中的char类型是一样的,8位,1个字节,-128-127。但是,char类型,是16位,2个字节, 'u0000'-'uFFFF'。

为什么java里的char是2个字节?

因为java内部都是用unicode的,所以java其实是支持中文变量名的,比如string 世界 = "我的世界";这样的语句是可以通过的。

综上,java中采用GB2312或GBK编码方式时,一个中文字符占2个字节,而char是2个字节,所以是对的

4. 以下哪项陈述是正确的?
A、 垃圾回收线程的优先级很高,以保证不再使用的内存将被及时回收
B、 垃圾收集允许程序开发者明确指定释放哪一个对象
C、 垃圾回收机制保证了JAVA程序不会出现内存溢出
D、 进入”Dead”状态的线程将被垃圾回收器回收
E、 以上都不对
参考答案:E 

  • 垃圾回收线程属于守护线程,只有所有用户线程都结束运行,才会随jvm一起结束, 优先级很低
  • 垃圾收集器(GC)程序开发者只能推荐JVM进行回收,但何时回收,回收哪些,程序员不能控制。
  • 垃圾回收机制只是回收不再使用的JVM内存,如果程序有严重BUG,照样内存溢出。
  • 进入DEAD的线程,它还可以恢复,GC不会回收

5. 下列哪个对访问修饰符作用范围由大到小排列是正确的?()
A、 public>protected>default>private
B、 public>default>protected>private
C、 private>protected>default>public
D、 private>default>protected>public
参考答案:A

6. 下列符号中可以在 java 程序里表示单行注释的是( )
A、 --
B、 
C、 //
D、 
参考答案:C 

  • -- sql注释
  •   块注释
  • //单行注释
  • 文档注释

7. Java 语言中创建一个对象使用的关键字是()
A、 class
B、 interface
C、 new
D、 create
参考答案:C

8. 下面关于 new 关键字的表述错误的是()
A、 new关键字在生成一个对象时会为对象开辟内存空间
B、 new关键字在生成一个对象时会调用类的构造方法
C、 new关键字在生成一个对象时会将生成的对象的地址返回
D、 Java中只能通过new关键字来生成一个对象
参考答案:D

生成一个对象:

  • new
  • 反序列化
  • 反射
  • 克隆

9. 有这样一段程序
public class Test{ 
    public static void main(String [] args){ 
        List list=new ArrayList(); 
        list.add("a");
        list.add("b");
        list.add("a");
        Set set=new HashSet(); 
        set.add("a"); 
        set.add("b"); 
        set.add("a"); 
       System.out.println(list.size()+","+set.size()); 
    } 
}
请问运行主要的程序会打印出的是什么()
A、 2,2
B、 2,3
C、 3,2
D、 3,3
参考答案:C

  • list可重复,size为3
  • set会去重,size为2

10. 当你编译和运行下面的代码时,会出现下面选项中的哪种情况?( )
public class Pvf{
    static boolean Paddy;
    public static void main(String args[]){
        System.out.println(Paddy);
    }
}
A、 编译时错误
B、 编译通过并输出结果false
C、 编译通过并输出结果true
D、 编译通过并输出结果null
参考答案:B

static boolean Paddy; //成员变量,有默认值  false

11. 给定以下JAVA代码,这段代码运行后输出的结果是()
public class Test

    public static int aMethod(int i)throws Exception
    {
        try{
            return i/10;
        }
        catch (Exception ex)
        {
            throw new Exception("exception in a aMethod");
        }finally{
      System.out.printf("finally");
        }

    public static void main(String[] args){
        try
        {
            aMethod(0);
        }
        catch (Exception ex)
        {
            System.out.printf("exception in main");
        }
       System.out.printf("finished");
    }
}

A、 exception in main finished
B、 finallyfinished
C、 exception in main finally
D、 finally exception in main finally
参考答案:B

0/10永远不会出错,10/0会出异常

12. 假设 A 类有如下定义,设 a 是 A 类同一个包下的一个实例,下列语句调用哪个是错误的?()
class A{
    int i;
    static String  s;
    void method1() {   }
    static void  method2()  {   }
}
A、 System.out.println(a.i);
B、 a.method1();
C、 A.method1();
D、 A.method2()
参考答案:C

method1不是静态的,不能用类名A调用。

13. 关于如下程序的描述哪个是正确的?( )
public class Person{
    static int arr[] = new int[5];
    public static void main(String a[]){
        System.out.println(arr[0]);
    }
}
A、 编译将产生错误
B、 编译时正确,但运行时将产生错误
C、 正确,输出0
D、 正确,输出 null
参考答案:C

  • 基本类型,默认0;本题数组为int类型
  • 引用类型,默认null

14. 执行下列代码的输出结果是( )

public class Demo {
    public static void main(String args[]) {
        int num = 10;
        System.out.println(test(num));
    }

    public static int test(int b) {
        try {
            b += 10;
            return b;
        } catch (RuntimeException e) {
        } catch (Exception e2) {
        } finally {
            b += 10;
            return b;
        }
    }
}


A、 10
B、 20
C、 30
D、 40
参考答案:C

15. 下列说法正确的是( )
A、 volatile,synchronized 都可以修改变量,方法以及代码块
B、 volatile,synchronized 在多线程中都会存在阻塞问题
C、 volatile能保证数据的可见性,但不能完全保证数据的原子性,synchronized即保证了数据的可见性也保证了原子性
D、 volatile解决的是变量在多个线程之间的可见性、原子性,而sychroized解决的是多个线程之间访问资源的同步性
参考答案:C 

  • volatile不能修改变量,方法以及代码块
  • volatile指定排序,不会出现阻塞问题
  • volatile没有原子性

16. 下面程序的运行结果是:( )
public static void main(String args[]) {
    Thread t = new Thread() {
           public void run() {
                pong();
           }
     };
 
    t.run();
    System.out.print("ping");
}
 
static void pong() {
System.out.print("pong");
}

A、 pingpong
B、 pongping
C、 pingpong和pongping都有可能
D、 都不输出
E、 pong
F、 ping
参考答案:B

t.run()没有开始线程,只是执行run方法,先输出pong,后输出ping

17. 根据以下代码段,下列说法中正确的是( )。
public class Parent {
    private void m1(){}
    void m2(){}
    protected void m3(){}
    public static void m4(){}
}
A、 子类中一定能够继承和覆盖Parent类的m1方法
B、 子类中一定能够继承和覆盖Parent类的m2方法
C、 子类中一定能够继承和覆盖Parent类的m3方法
D、 子类中一定能够继承和覆盖Parent类的m4方法
参考答案:C

default修饰m2

18.ResultSet中记录行的第一列索引为?
A、 -1
B、 0
C、 1
D、 以上都不是
参考答案:C

设置参数、取结果集   索引都是从1开始

19. 以下JAVA程序的运行结果是什么( )
public static void main(String[] args) {
    Object o1 = true ? new Integer(1) : new Double(2.0);
    Object o2;
    if (true) {
    o2 = new Integer(1);
    } else {
        o2 = new Double(2.0);
    }
    System.out.print(o1);
    System.out.print(" ");        
    System.out.print(o2);
}

A、 1 1
B、 1.0   1.0
C、 1     1.0
D、 1.0  1
参考答案:D 

最终返回值double类型,取决于最大的那个类型。

new Integer(1)  --> 1.0

20. 当WHERe子句、GROUP BY子句、HAVINg子句、ORDER BY子句同时出现在一个SQL查询语块中时,最后执行的()
A、 WHERe子句
B、 GROUP BY子句
C、 HAVINg子句
D、 ORDER BY子句
参考答案:D

写sql顺序:

  1. select
  2. from
  3. join
  4. where
  5. group by
  6. having
  7. union
  8. order by
  9. limit

sql解析顺序:

  1. from
  2. where
  3. join
  4. group by
  5. having
  6. union
  7. select 
  8. order by
  9. limit

21. 检索销量表中销量最好的商品id和销量(假设每件商品只有一个订单),下列SQL语句正确的是()
A、 SELECT 商品id,销量 FROM 销量表 WHERe 销量=MAX(销量)
B、 SELECt 商品id,MAX(销量) FROM 销量表 GROUP BY 销量
C、 SELECt 商品id,MAX(销量) FROM 销量表 GROUP BY 商品id
D、 SELECt 商品id,销量 FROM 销量表WHERe 销量=(SELECt MAX(销量) FROM 销量表)
参考答案:D

A: MAX写错位置,没有这种写法

B: select后的字段要有分组后面的字段

C: 题中只需查询一条,C会查出每个id的销量值

D:  只会查出来一条,正确

22. Mysql中表student_table(id,name,birth,sex),插入如下记录:
('1003' ,'男生姓名' , '2000-05-20' , '男');
('1004' , '张三' , '2000-08-06' , '男');
('1005' , '李四' , '2001-12-01' , '女');
('1006' , '女生姓名' , '2001-12-02' , '女');
删除符合条件的记录:是男生时删除name='男生姓名'的记录,是女生时删除name='女生姓名'的记录,如下SQL正确的是()?
A、 delete from table student_table where  name  = ( case when sex = '男' then '男生姓名' when sex = '女' then '女生姓名' end) ;
B、 delete from student_table where  name  = ( case when sex = '男' then '男生姓名' when sex = '女' then '女生姓名' end) ;
C、 delete from student_table where  name  = ( case when sex = '男' then '男生姓名' when sex = '女' then '女生姓名') ;
D、 delete from student_table where  name  = ( case sex = '男' then '男生姓名' case sex = '女' then '女生姓名' end) ;
参考答案:B

case when end

先判断是不是男生,再判断是不是女生

23. Mysql中表student_table(id,name,birth,sex),插入如下记录:
('1001' , '' , '2000-01-01' , '男');
('1002' , null , '2000-12-21' , '男');
('1003' , NULL , '2000-05-20' , '男');
('1004' , '张三' , '2000-08-06' , '男');
('1005' , NULL , '2001-12-01' , '女');
('1006' , '张三' , '2001-12-02' , '女');
执行
 select t1.name from 
 (select * from student_table where sex = '女')t1       后两条 1005和1006
 inner join 
 (select * from student_table where sex = '男')t2       前四条1001、1002、1003、1004
 on t1.name = t2.name;
的结果行数是()?
A、 4
B、 3
C、 2
D、 1
参考答案:D

查出来的是 ('1006' , '张三' , '2001-12-02' , '女'); 

在数据库中NULL表示 未知的。NULL不等于零或空格,NULL 值不视作大于、小于或等于任何其它值。当一个变量、列或常量具有NULL值时,它的值是未知的、不确定的。

定义为NOT NULL的字段只能插入空值,不能插入null值,而NULL字段可以插入空值,也可以插入null值。

1、空值不占空间;

2、null值占空间。

24. 有一张person表,主键是id,数据如下:

同时还有一张任务表task,主键也是id:


请找出每个人的任务情况(注意:没有任务也要输出),结果按id降序排列,输出如下:
 
下面正确的SQL查询语句是:(    )
A、 SELECt p.id, p.name, t.content FROM person AS p LEFT JOIN task AS t ON p.id = t.person_id ORDER BY p.id DESC;
B、 SELECt p.id, p.name, t.content FROM person AS p JOIN task AS t ON p.id = t.person_id ORDER BY p.id DESC;
C、 SELECt p.id, p.name, t.content FROM person AS p RIGHT JOIN task AS t ON p.id = t.person_id ORDER BY p.id DESC;
D、 SELECt p.id, p.name, t.content FROM person AS p INNER JOIN task AS t ON p.id = t.person_id ORDER BY p.id DESC;
参考答案:A

(注意:没有任务也要输出)表示:以person为主表

25. 以下程序执行的结果是:( )
class X{
       Y y=new Y();
       public X(){
              System.out.print("X");
       }
}
class Y{
       public Y(){
              System.out.print("Y");
       }
}
public class Z extends X{
       Y y=new Y();
       public Z(){
              System.out.print("Z");
       }
       public static void main(String[] args) {
              new Z();
       }
}

A、 ZYXX
B、 ZYXY
C、 YXYZ
D、 XYZX
参考答案:C

二、多选题 

1. java中下面哪些是Object类的方法()
A、 notify()
B、 notifyAll()
C、 sleep()
D、 wait()
参考答案:A,B,D 

C: sleep()是Thread的方法,clone()也是Object的方法

2. 关于Java以下描述正确的有( )
A、 Class类是Object类的超类
B、 Object类是一个final类
C、 String类是一个final类
D、 Class类可以装载其它类
参考答案:C,D

A: Object是java的最大基类,Class是反射

B: Object能被继承

3. 下面的对象创建方法中哪些会调用构造方法 ()?
A、 new语句创建对象
B、 调用Java.io.ObjectInputStream的readObject方法
C、 java反射机制使用java.lang.Class或java.lang.reflect.Constructor的newInstance()方法
D、 调用对象的clone()方法
参考答案:A,C

B: 反序列化不会调用构造方法

D: clone()不会调用构造方法,跟Object一样有自己的机制

4. 关于以下方法调用描述正确的是:()
private static final List list = new ArrayList<>();
public static String test(String j){
    int i = 1, s = 1, f = 1, a = 1, b = 1,c = 1,d = 1,e = 1;
    list.add(new String("11111111111111111111111111111"));
    return test(s+i+f+a+b+c+d+e+"");
}
A、 一定会发生” OutOfMemoryError: Java heap space”
B、 一定会发生” StackOverflowError”
C、 一定会发生” OutOfMemoryError: Java heap space与StackOverflowError”
D、 当发生内存溢出错误时不需要用try…catch来捕获,需检查代码及jvm参数配置的合理性
参考答案:B,D

递归调用自己,没有边界条件,会一直调自己,一定会发生栈(虚拟机栈)溢出,方法调用次数过多。

不属于异常,属于错误,错误不能用来捕获。

错误一般发生在严重故障时,它们在Java程序处理的范畴之外。

5. 下面哪些写法能在 java8 中编译执行()
A、 dir.listFiles((File f)->f.getName().endsWith(“.Java”));
B、 dir.listFiles((File f)=>f.getName().endsWith(“.Java”));
C、 dir.listFiles((_.getName().endsWith(“.Java”)));
D、 dir.listFiles( f->f.getName().endsWith(“.Java”));
参考答案:A,D

B:  java   -> 

     javascript   =>

C:  _错误

6. 在MySql中进行数据查询时,如果要对查询结果的列名重新命名,将sno列重新命名为学号,则下列语句正确的是( )
A、 select sno as 学号 from T
B、 select 学号= sno from T
C、 select sno 学号 from T
D、 select sno=学号 from T
参考答案:A,C

重新命名:一种加as,一种不加as。

7. Java创建对象的说法正确的有()


A、 用new语句创建对象,是最常见的创建对象的方法。
B、 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
C、 调用对象的clone()方法。
D、 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
参考答案:A,B,C,D

8. 下面关于面向对象的一些理解哪些是错误的( )
A、 面向对象的最重要的特性是支持继承、封装和多态
B、 系统设计应该遵循开闭原则,系统应该稳定不可修改,但应支持通过继承、组合等方式进行扩展
C、 函数式的语言必然是面向对象的语言
D、 面向对象设计时,每个类的职责应该单一,不要再一个类中引入过多的接口
E、 过程式语言和面向对象的语言各有其优势,过程式语言更加灵活,面向对象语言更加强调抽象和封装
F、 Java和C++都是静态类型的面向对象编程语言
参考答案:C

在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。

JavaScript面向对象语言,天生就是多态。【var什么类型运行出来才会知道】

9. 局部内部类可以用哪些修饰符修饰?( )
A、 public
B、 private
C、 abstract
D、 final
参考答案:C,D

可以将局部内部类看成一个局部变量,写局部变量时不会用public和private修饰

10. 下列代码哪些是正确的( )
A、 Statement sta=con.createStatement();
        ResultSet rst=sta.executeQuery("select * from book");
B、 Statement sta=con.createStatement("select * from book"); 
        ResultSet rst=sta.executeQuery();
C、 PreparedStatement pst=con.prepareStatement();
        ResultSet rst=pst.executeQuery("select * from book");
D、 PreparedStatement pst=con.prepareStatement("select * from book");
        ResultSet rst=pst.executeQuery();
参考答案:A,D

三、填空题


1. Java语言规定标识符由_____、_____ 、____ 和数字组成,并且第一个字符不能是____ 

1、 字母
2、 美元符号
3、 下划线
4、 数字

2. Java中包含 ___________________________ 等8种基本数据类型。

byte  short  int  long  float  double  boolean  char

3. 自定义线程的实现可以通过                           方式实现。

1、 继承thread
2、 实现runnable接口

4. 集合中,LinkedList采用了双向链表数据结构作为实现,而HashMap通过_________、_________ 、_________ 作为底层数据结构实现。

1、 数组
2、 链表
3、 红黑树

5. 在Java中,可以通过Fle类中的_____方法判断文件是否存在,通过____方法建立多级文件夹。

1、 exists()
2、 mkdirs()

6. 数据库中,事务的四大特性包括 。

原子性、一致性、隔离性、持久性

7. MySQL中,事务的隔离别级别包括________________,MySQL默认采用的是 ___________。

1、 读未提交,读已提交,可重复读,可串行化读
2、 可重复读

四、简答题

1. 请简述JAVA中List、Set、Map集合的特点及其实现类。详细说明各实现类的特点及区别。
List接口

List可以存储重复的元素。主要有两种实现:ArrayList和LinkedList。

ArrayList没有什么好说的,就像传统的数组一样,有着很快的随机存取速度,但是插入删除的速度就很慢。

LinkedList则与ArrayList恰恰相反,因为用链表来保存数据,所以插入删除元素的速度很快,但是访问数据的速度就不如ArrayList了。

Set接口

Set不允许出现重复的元素,并且元素之间没有次序。添加进Set的元素类型需要定义equals方法。若是使用自定义的类,则应该重写equals方法来确保实现自己需要的功能。

Set接口主要实现了两个类:HashSet,TreeSet。

HashSet是按照哈希来存取元素的,因此速度较快。HashSet继承自抽象类AbstractSet,然后实现了Set、Cloneable、Serializable接口。

TreeSet也是继承自AbstractSet,不过不同的是其实现的是NavigableSet接口。NavigableSet继承自SortedSet。SortedSet是一个有序的集合。其添加的元素必须实现了Comparable接口,因为其在添加一个元素的时候需要进行排序。NavigableSet则提供了更多的有关元素次序的方法。

LinkedHashSet也是Set的一个实现。和HashSet类似,只不过内部用链表来维护,按照元素插入次序来保存。

Map接口

Map(映射)是一个存储键值对的容器接口。每一个元素包含一个key对象和value对象,且元素不允许重复。

Map接口的实现有以下几个:

HashMap是最常用的一个实现。HashMap使用hash映射来存取数据,这个速度是相当快,是O(1)的速度。其容量capacity,和负载因子load factor可以在一开始设定。当元素个数达到capacity*load factor的时候,就会进行扩容。

LinkedHashMap和HashMap类似,只不过内部用链表来维护次序。因此遍历时候的顺序是其插入顺序。

TreeMap是基于红黑树的Map,插入的数据被有次序保存,并且有很高的效率。因此在遍历输出的时候可以得到排序的数据。但是这要求插入的数据实现了comparable接口。

总结

Collection、Set、List和Map都是接口,不能被实例化。

Set和List都继承自Collection,而Map则和Collection没什么关系。

Set和List的区别在于Set不能重复,而List可以重复。

Map和Set与List的区别在于,Map是存取键值对,而另外两个则是保存一个元素。

参考答案: 
1.请简述JAVA中List、Set、Map集合的特点及其实现类。详细说明各实现类的特点及区别。
正确阐述各接口的特点  2分
能够正确阐述各实现类,ArrayList、LinkedList、HashSet、TreeSet、HashMap各接口特点  0~3分


2. 详细说明String、StringBuffer、StringBuilder的区别

String类不可变,对象一旦被创建就不能被修改,可以用=赋值使用常量池,也可以用new创建;

StringBuffer类可变,对象创建后可修改,必须用new关键字,保持线程同步,多线程操作;

StringBuilder类可变,创建对象后可修改,必须用new关键字,不保证线程同步,单线程使用比较高效。

参考答案: 
1.详细说明String、StringBuffer、StringBuilder的区别
能够分别概述三种类的作用和特点  1分
能够说明String是final修饰,无法被继承  2分
能够强调线程安全性及性能方面问题   2分

 
3. 阐述你所理解的JVM垃圾回收机制

无永久代,运行时常量池、类常量池都保存到元数据区,也就是常说的元空间。但字符串常量池仍存在堆中。

JVM在运行Java程序时,会把管理的内存划分为若干个区域,每个区域都有自己的用途和创建销毁时间。如下图所示,可以分为两大部分,线程私有区域和线程共享区域。

线程私有区域包括:虚拟机栈、本地方法栈、程序计数器

线程共享区域包括:Java堆、方法区。

 

线程私有区域
虚拟机栈
线程私有的,与线程同一时间创建,管理Java方法执行时的内存模式。每个方法执行的时候都会创建一个帧栈来储存方法的局部变量表、操作数帧、动态链接方法、返回值、返回地址等信息。栈的大小决定了方法可调用的深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈的大小可以是固定的,或者是动态扩展的。如果请求的深度超过最大可用深度,则会抛出stackOverflowError错误;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出OutofMemeryError错误。

  • 局部变量表:是一组变量值存储空间,存放方法的参数以及局部变量,以及编译期间可知的八大基本数据类型,对象引用和 returnAddress类型(指向了一条字节码指令的地址)。
  • 操作数帧:保存计算过程中的中间结果,同时作为计算过程中变量的临时储存空间。

本地方法栈
与虚拟机栈结构作用相似。不同的是虚拟机栈为Java方法服务,本地方法栈为本地方法服务(native方法)。

程序计数器
较小的内存空间,记录这当前线程所执行的字节码的行号,字节码解析的时候通过改变程序计数器的值来获取下一条需要执行的指定。在多线程程序中,每个线程都有独立的程序计数器,所以程序计数器是私有的。如果程序执行的是Java方法,那么这个程序计数器记录着当前执行的字节码指令地址,如果执行的是一个navtive方法,则计数器为空。程序计数器区域没有任何OutOfMemoryError定义。

线程共享区域
Java堆
Java堆是被所有线程共享的一块内存区域,存放对象实例和数组,是垃圾回收的主要区域,分为新生代和老生代。刚创建的对象在新生代Eden区中,经过GC后进入新生代的S0区,再经过GC进入新生代的S1区,15次GC后扔存在则进入老生代。若堆的空间不够实例的分配,则会抛出OutofMemeryError错误。

JDK8元空间
元空间是从虚拟机Java堆中转移到本地内存,默认情况下,元空间的大小受本地内存的限制,说白了也就是以后不会因为永久代空间不够而抛出 OOM 异常出现了。 jdk1.8 以前版本的 class 和 JAR 包数据存储在 PermGen 下面 PermGen 大小是固定的,而且项目之间无法共用,公有的 class ,所以比较容易出现 OOM 异常。

方法区
方法区是线程共享的,用于存放虚拟机加载的类信息、常量、静态变量以及即时编译期编译后的代码。

垃圾回收器的作用是查找和回收(清理)无用的对象。以便让JVM更有效的使用内存。

第一种:引用计数法
实现:对于一个对象A,只要任何一个对象引用了A,那么A的引用计数器就加1,当引用失效时,引用计数器就减1。只要引用计数器的值为0,那么就表示对象A不可能再被引用。
好处:使用古老,容易实现;
坏处:当循环引用的时候,容易导致内存泄露问题;A引用了B,B也引用了A,这样始终不会释放,导致内存泄露(不可达的对象)。

第二种:标记-清除算法
实现:分为两个阶段,标记阶段和清除阶段。在标记阶段,从根节点开始,对每一个可达性的对象进行标记,没有被标记的的对象,在第二个阶段,将会被清除。
好处:分层清晰,是现代垃圾回收算法的思想基础;
坏处:清除的时候,会产生很多时间碎片,大对象无法存放,出现很多不连续的空间,影响效率(我们知道,不连续的内存空间的工作效率要低于连续的空间);

第三种:复制算法
实现:将原有的内存空间分为2块,每次只使用一块,在垃圾回收的时候,将正在使用的内存中的存活的对象复制到另外未使用的内存块中,之后清除掉正在使用的内存块中的所有的对象,交换2个内存的角色。
好处:对于垃圾比较多的对象,效率很高;因为是复制到另外的内存里面的,所以空间是连续的;
坏处:对于存活对象很久的对象,会浪费性能;

注:因为JVM堆中的年轻代中大部分都是垃圾的对象,所以采用此复制算法来实现效率更高。

第四种:标记-压缩算法
实现:在标记阶段和标记-清除算法类似,都是先从根节点标记可达性的对象,只是在第二个阶段,需要对所有可达性的对象进行压缩,压缩到内存一端,之后,清理掉边界外的所有的空间。
好处:内存空间是连续的,避免的碎片的产生,性价比比较高;

注:比较适用于老年代的一种回收算法,因为老年代大部分都是长期存活的对象,不需要被回收的。

第五种:增量算法
实现:因为在GC运行的时候,所有的应用程序都是需要停下来的,这样如果回收的时间比较长,会出现卡顿的情况,影响用户体验;这时候可以采用增量的算法,每次针对一小块的内存区域进行垃圾回收,然后再自行一会儿线程,如此交换运行,直到GC清理完成。
好处:优化客户体验,减少卡顿产生;
坏处:因为GC和线程之间需要不断的切换,上下文的转换需要消耗资源,使得垃圾回收的成本上升了,降低了系统的吞吐量;

第六种:分代
实现:分代是一种思想,在垃圾回收的过程中,我们没办法一直采用一种算法来进行垃圾回收,每种垃圾回收算法都有自己独特的优点和特点,因此可以采用几种算法来进行。
以hotspot为例,年轻代采用的是复制算法,老年代采用的是标记-压缩算法,提高了垃圾回收的效率。

Java 中用于「回收垃圾」的常见算法有 4 种:

1.标记-清除算法(mark and sweep) 分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成之后 统一回收掉所有被标记的对象。 缺点:首先,效率问题,标记和清除效率都不高。其次,标记清除之后会产生大量的不 连续的内存碎片。

2.标记-整理算法 是在标记-清除算法基础上做了改进,标记阶段是相同的,但标记完成之后不是直接对 可回收对象进行清理,而是让所有存活的对象都向一端移动,在移动过程中清理掉可回收的 对象,这个过程叫做整理。 优点:内存被整理后不会产生大量不连续内存碎片。

3.复制算法(copying) 将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了, 就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。 缺点:可使用的内存只有原来一半。

4.分代收集算法(generation) 当前主流 JVM 都采用分代收集(Generational Collection)算法, 这种算法会根据对象 存活周期的不同将内存划分为年轻代、年老代、永久代,不同生命周期的对象可以采取不同的回收算法 ,以便提高回收效率。

(1) 年轻代(Young Generation)

 1.所有新生成的对象首先都是放在年轻代的。

 2.新生代内存按照8:1:1的比例分为一个eden区和两个Survivor(survivor0,survivor1) 区。大部分对象在 Eden 区中生成。回收时先将 eden 区存活对象复制到一个 survivor0 区, 然后清空 eden 区,当这个 survivor0 区也存放满了时,则将 eden 区和 survivor0 区存活 对象复制到另一个 survivor1 区,然后清空 eden 和这个 survivor0 区,此时 survivor0 区 是空的,然后将 survivor0 区和 survivor1 区交换,即保持 survivor1 区为空, 如此往复。

3.当 survivor1 区不足以存放 eden 和 survivor0 的存活对象时,就将存活对象直接存 放到老年代。若是老年代也满了就会触发一次 Full GC,也就是新生代、老年代都进行回收。

4.新生代发生的 GC 也叫做 Minor GC,MinorGC 发生频率比较高(不一定等 Eden 区 满了才触发)

(2)年老代(Old Generation)

1.在年轻代中经历了 N 次垃圾回收后仍然存活的对象,就会被放到年老代中。因此, 可以认为年老代中存放的都是一些生命周期较长的对象。

2.内存比新生代也大很多(大概是 2 倍),当老年代内存满时触发 Major GC 即 Full GC, Full GC 发生频率比较低,老年代对象存活时间比较长,存活率比较高。

(3)持久代(Permanent Generation)

用于存放静态文件,如 Java 类、方法等。持久代对垃圾回收没有显著影响,从 JDK8 以后已经废弃, 将存放静态文件,如 Java 类、方法等这些存储到了元数据区.

参考答案: 
能够大体说明JVM内存模型  1分
能够说明垃圾回收的作用  1分
能够阐述垃圾回收中的算法实现思想 2分
能够表述jvm使用垃圾回收方式方法  1分


4. 请详细阐述final及static关键字的特点

final可以修饰变量、方法及类:

  1. 当定义一个final变量时,jvm会将其分配到常量池中,程序不可改变其值;
  2. 当修饰一个方法时,该方法在子类中将不能被重写;
  3. 当修饰一个类时,该类不能被继承。

static是静态修饰关键字,可以修饰变量和程序块以及类方法:

  1. 当定义一个static的变量的时候jvm会将将其分配在内存堆上,所有程序对它的引用都会指向这一个地址而不会重新分配内存;
  2. 当修饰一个程序块的时候(也就是直接将代码写在static{...}中)时候,虚拟机就会优先加载静态块中代码,这主要用于系统初始化;
  3. 当修饰一个类方法时候你就可以直接通过类来调用而不需要新建对象。

final stati含义

表示 static修饰的属性强调它们只有一个,final修饰的属性表明是一个常数(创建后不能被修改)。static final修饰的属性表示一旦给值,就不可修改,并且可以通过类名访问。

参考答案: 
能够说明final作用  1分
能够说明final的使用场景及特点 1分
能够说明static作用 1分
能够说明static的使用场景及特点2分

 
5. 请编写伪代码说明JDBC执行的完整流程,同时阐述PreparedStatement与Statement之间的区别。

区别:

  1. PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高
  2. 使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。
  3. statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement预编译得, preparedstatement支持批处理 。
  4. 执行许多SQL语句的JDBC程序产生大量的Statement和PreparedStatement对象。通常认为PreparedStatement对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。PreparedStatement对象允许数据库预编译SQL语句,这样在随后的运行中可以节省时间并增加代码的可读性。
  5. PreparedStatement 可以规避 Statement弊端:①拼串 ②sql注入问题
  6. PreparedStatement 可以实现操作Blob类型、Clob类型的数据
     

联系:

  1. PreparedStatement继承自Statement
  2. PrerapedStatement和Statement都是接口
  3. PreParedStatement和Statement都可以实现对数据表的CRUD操作:增删改查

参考答案: 
正确编写整体流程  1分
能够正确使用异常处理  1分
能够释放资源   1分
能够完整正确阐述PreparedStatement与Statement之间的区别  2分

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/889122.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号