Java面试题-Java基础

这篇博客汇总了Java面试中常见的基础问题,包括Java的基本数据类型、面向对象特性、JDK、JRE和JVM的区别、反射机制、异常处理、以及类和对象的创建等核心概念。同时,探讨了String类、equals与==的区别、泛型、Java8新特性、并发编程模型(BIO、NIO、AIO)以及异常处理策略等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java面试题

JAVA 基础

1. JAVA中的几种基本数据类型是什么,各自占用多少字节。

基本类型	所占字节	基本类型	所占字节
byte	   1	boolean	未明确规定
short	   2	char	   2
int	       4	float	   4
long	   8	double	   8
注意:一个字节等于8位。各个类型的取值范围是-2的位数次幂到2的位数-1

2.String类能被继承吗,为什么。

String类是被final修饰的,被final修饰的类是不能被继承的。
拓展1:什么情况下子类不能够继承?
     1.上面提到过的被final修饰的类,变量和方法。
     2.父类中被private修饰的方法和变量是不能被继承的。
     特别说明:
     静态方法和变量也是可以继承的,只是不能被重写,如果子类中存在与父类同名的方法或变量,那么这个变量
     或方法是子类特有的,跟父类没有关系。
     final修饰的方法和属性是不能被继承的。
拓展2:上面提到了父类中被private修饰的方法和变量是不能被继承的,那么问题来了,父类的构造方法被
      private修饰,子类还可以继承父类吗?
      答案:父类的构造方法被private修饰,子类是不能被子类继承的。因为初始化子类的时候,
      父类的构造方法是不可以被执行的。
拓展3:String、StringBuffer、StringBuilder有什么区别。
      答案:1.可变与不可变
          String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象
          是不可变的。
         private final char value[];
          StringBuilder与StringBuffer都继承AbstractStringBuilder,AbstractStringBuilder
          中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。
         char[] value;
           2.是否多线程安全
          String中的对象是不可变的,也就可以理解为常量,显然线程安全。
          AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的
          基本操作,如expandCapacity、append、insert、indexOf等公共方法。
          StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
           最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。

3.什么是面向对象?有什么特性?请分别解释一下。

面向对象是一种思想,将复杂的问题简单化,让我们从执行者变为指挥者。它有三大特性分别是:
继承:已知类派生出一个新类,新类拥有已知类所有的非private方法和变量。并且新类可以通过重写/覆盖来拓展自己。
封装:将Java代码封装成类,减少耦合,隐藏细节。对外保留接口,当代码内部发生改变时不会影响外部调用方。
多态:实现多态有三个必要条件分别是继承、重写、父类引用指向子类对象。

4.JDK,JRE和JVM的区别与联系有哪些。

JDK:JDK是Java开发工具包,是Java开发环境的重要组件,包括编译、调试和运行。
JRE:JRE是Java运行环境,提供了Java程序运行平台。
JVM:JVM是Java虚拟机,它负责将字节码文件转换为特定平台的机器码。JVM还包括垃圾回收机制。
总结:它们三者是包含的关系JDK包含JRE和JVM,JRE包含JVM。
拓展1:Java是编译型语言还是解释型语言?
      答案:Java是先编译后解释的语言。
拓展2:什么是JIT编译器。
      答案:JIT编译器全名叫Just In Time Compile 也就是即时编译器,把经常运行的代码作为"热点代码"
      编译成与本地平台相关的机器码,并进行各种层次的优化。JIT编译除了具有缓存的功能外,还会对代码做
      各种优化,包括逃逸分析、锁消除、 锁膨胀、方法内联、空值检查消除、类型检测消除以及公共子表达式
      消除等。

在这里插入图片描述

5.抽象类和接口有什么区别。

1.抽象类和接口都不能被实例化。
2.抽象类只能是单继承,并且可以实现接口;接口可以多继承,但是接口只能继承接口,不能继承抽象类。
3.抽象类中可以包括普通成员和抽象成员变量;接口中没有变量只有常量。
4.抽象类中含有普通方法和抽象方法;接口在jdk1.8之前不存在普通方法,在jdk1.8的时候接口允许拥有
  非抽象方法
拓展1:抽象类中的方法不能被什么修饰符修饰?
      答案:分别是finalstaticsynchronizednative。
拓展2:接口中的成员变量和方法默认修饰符分别是什么?
      答案:成员变量默认修饰符是public static final;方法默认的修饰符是public abstract
拓展3:jdk1.8的接口中为什么会出现default方法?
      答案:为了不影响已经实现的子类,接口中出现了default方法,这样既可以拓展接口中的方法,又可以
      不修改已经实现的子类中的代码结构。
拓展4:为什么类只能单继承,接口可以多继承?
      答案:子类如果能继承多个父类,如果多个父类中存在同名属性或者方法,
      子类继承时将不能判断继承自哪个父类的属性和方法,所以类之间不能多继承。
      然而接口全部都是抽象的不存在类与类之间的问题。

6.Java中的元注解都有哪些。

1.@Target,该注解是注解其他注解的注解。
源码如下:

public @interface Target { 
    ElementType[] value(); 
} 
public enum ElementType { 
  TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE 
} 

Target的使用示例

@Target({ElementType.TYPE, ElementType.METHOD}) 
public @interface MyAnnotation { 
}

2.@Retention,注解的保留策略,也就是注存活的时间。
源码如下:

public @interface Retention { 
    RetentionPolicy value(); 
} 
public enum RetentionPolicy { 
    SOURCE, CLASS, RUNTIME 
}

3.@Documented,其他类型的注解被该注解标记会被作为公共api,会被javadoc文档化。
源码如下:

public @interface Documented {
}

4.@Inhertied,该注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
源码如下:

public @interface Inherited {
}

7.解释一下Java中的反射机制。

   在运行中,对于一个类来说都能够知道这个类的方法和属性;对于一个对象来说,都能够调用它的所有方法,
这种动态的获取类信息和对象方法的功能称为反射。
拓展1:在Java反射机制中获取Class类有哪三种方式?
      答案:1.对象.getClass();2.类名.class;3.Class.forName(类的全限定路径);
拓展2:既然提到了Class.forName(),那么请说一下Class.forName()和ClassLoader有什么区别?
	  答案:Class.forName(className),实际调用的是Class.forName(className,true,classloader).
	  true代表的是要被初始化。所以使用Class.forName(className)方法的时候会触发目标对象初始化
	  一旦初始化,就会加载类中的static成员变量和static代码块。
	  ClassLoader实际调用的是ClassLoader.loadClass(className,false),false代表不会初始化
	  所以ClassLoader是不会将目标对象进行初始化的。
拓展3:反射机制有什么作用?
	  答案:1.在运行时判断任意一个对象所属的类
           2.在运行时构造一个类的对象
           3.在运行时判断任意一个类所具有的成员变量和方法
           4.在运行时调用任意一个对象的方法,生成动态代(dai)理

8.Java中的Exception和Error有什么区别。

Exception:程序正常运行中预料到可能会出现的错误,并且应该被捕获并进行相应的处理,是一种异常现象。
Error:是正常情况下不可能发生的错误,Error会导致JVM处于一种不可恢复的状态,不需要捕获处理
       比如说OutOfMemoryError
拓展1:Exception中的运行时异常和检查时异常有什么区别。
	 答案:1.运行时异常:表示的是在运行时发生的异常,比如空指针异常,数组越界,数字转换异常等。
	      2.检查时异常:表示的是编译器在编译的时候可能出现的异常,需要我们必须去处理,捕捉或
	      抛出异常。
拓展2:请列出五个运行时异常。
      答案:1.ArrayIndexOutOfBoundsException:数组越界
           2.ClassCastException:类型转换异常
           3.NullPointerException:空指针异常
           4.ArraytStoreException:数组类型不匹配
           5.BufferOverFlowException:缓冲区写入的长度超过了允许的长度

9.解释一下Java中的值传递与引用传递。

1.值传递:意味着传递了对象的一个副本,即使副本被改变,也不会影响源对象。
2.引用传递:意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象的改变会反映到所有的对象
  上。
拓展:Java中真的存在引用传递吗。
	 答案:引用传递,实际上传递的是对象在堆中的地址,地址也是值,本质上引用传递也是值传递。所以Java
	 不存在引用传递的。

10.Java中序列化和反序列化

Java 序列化是指把 Java 对象转换为字节序列的过程;
Java 反序列化是指把字节序列恢复为 Java 对象的过程;
拓展1:为什么要用序列化与反序列化。
     答案:1.把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
          2.在网络上传送对象的字节序列。
拓展2:如果有些字段不想进行序列化怎么办。
	  答案:对于不想进行序列化的变量,使用transient关键字修饰。 
拓展3:除了transient关键字之外,还有其他被关键字修饰不可以被序列化吗。
      答案:序列化存储的是对象的状态,类的状态不存储。
拓展4:反序列化会遇到什么问题,怎么解决。
 	  答案:反序列化可能会遇到serialVersionUID不一致的问题。
 	  解决方案:在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。

11.equals和hashCode方法的关系。

1. 如果两个对象相等,则hashcode一定也是相同的 
2. 两个对象相等,对两个对象分别调用equals方法都返回true 
3. 两个对象有相同的hashcode值,它们也不一定是相等的 
4. 因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖 
5. hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象
   无论如何都不会相等(即使这两个 对象指向相同的数据) 

12.Java和C++的区别有哪些。

1.都是面向对象的语言,都支持封装、继承和多态 
2.Java 不提供指针来直接访问内存,程序内存更加安全 
3.Java 的类是单继承的,C++ 支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。 
4.Java 有自动内存管理机制,不需要程序员手动释放无用内存 

13.静态与非静态的区别。

1. 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对 象名.方法名"的方式。而实例方法
   只有后面这种方式。也就是说,调用 静态方法可以无需创建对象。
2. 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量 和静态方法),而不允许访问实例
   成员变量和实例方法;实例方法则无此限制. 

14.Java中equals方法和==的区别。

1.== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象
 是不是同 一个对象。(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) 
2.equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况: 
  1.类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个 对象时,等价于通过“==”比较这两个对象。 
  2.类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来 两个对象的内容相等;
  若它们的内容相等,则返回 true (即,认为这两 个对象相等)

15.重载和重写的区别。

1.重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,
  方法返回值和访问修饰符可以不同,发生在编译时。    
2.重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围
  小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。 

16.类的实例化顺序。

1.父类的静态成员变量和静态代码块
2.子类的静态成员变量和静态代码块
3.父类的成员变量和代码块,然后加载构造方法
4.子类的成员变量和代码块,然后加载构造方法

17.继承和聚合的区别在哪。

1.继承
  指的是一个类继承另外的一个类的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常
  见的关系;在Java中此类关系通过关键字extends明确标识。
2.聚合
  聚合体现的是整体与部分、拥有的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期;
  比如计算机与CPU、公司与员工的关系等;

18.BIO、NIO、AIO是什么,reactor 又是什么。

1.BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程
  并处理,如果这个连接不做任何事情会造成不必要的开销,当然可以通过线程池机制改善
2.NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,
  多路复用器轮询到连接有IO请求时才启动一个线程进行处理
3.AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了
  再通知服务器应用去启动线程进行处理
4.reactor:nio只有acceptor的服务线程是堵塞进行的,其他读写线程是通过注册事件的方式,
  有读写事件激活时才调用线程资源区执行,不会一直堵塞等着读写操作,Reactor的瓶颈主要在于
  acceptor的执行,读写事件也是在这一块分发

19.final 的用途。

1.final修饰的类是不可以被继承的;
2.final修饰的方法是不可以被重写的;
3.final修饰的变量是不可变的。
拓展1finalfinally和finalize的区别
	 答案:1.final:java中的关键字,修饰符。
          2.finally:java的一种异常处理机制。
           finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管无异常发生。
           使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,
           如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。
          3.finalize:Java中的一个方法名。
            Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。
            这个方法是由垃圾收集器在确定这个对象没被引用时对这个对象调用的。它是在Object类中定义的
            因此所的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作
            。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
拓展2:如果执行finally代码块之前方法返回了结果,或者JVM退出了,finally块中的代码还会执行吗.
      答案:1.如果执行finally代码块之前方法返回了结果,这种情况finally是会执行的。
           2.try语句没有被执行到和在try/catch块中有System.exit(0)来退出JVM,finally
             中的代码就不会被执行的。

20.修饰符 public、private、protected、default 在应 用设计中 的作用和区别。

关键字	类内部	本包	  子类	外部包
public 	  √	     √	   √	  √
protected √	     √	   √	  ×
default   √	     √	   ×	  ×
private	  √	     ×	   ×	  ×
拓展:public static void 写成 static public void会怎样。
     答案:程序正常编译运行。publicstatic没有顺序限制,但是必须都在void前面。

21.自定义的java.lang.String 类,会被类加载器加载吗。

不可以,双亲委派模式会保证父类加载器先加载类,就是BootStrap(启动类)加载器加载jdk里面的
java.lang.String类,而自定义的java.lang.String类永远不会被加载到。
拓展1:自定义的com.djx.String会被加载吗。
      答案:在main方法启动的时候会报错,找不到主类。将mian方法参数中的String改为java.lang.String
      可以解决问题。
拓展2:自定义的java.lang.String会被加载吗。
	  答案:首先由于全限定类名java.lang.String等于jdk中的String类,根据上边类加载源码可知,当
	  AppClassLoader加载该String时,判断java.lang.String已经加载,便不会再次加载。所以执行的
	  依旧是jdk中的String,但是系统的java.lang.String中没有main()方法,所以会报错。这是一种安
	  全机制。

22.深拷贝和浅拷贝区别。

1.浅拷贝:拷贝是引用,也就是创建一个新的引用,但是新的引用依然指向原来的对象。
2.深拷贝:拷贝的是引用和对象,也就是创建了一个新的引用和新的对象,并且新的引用指向新的对象。

23.Java中的泛型用来解决什么问题。

泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。

泛型主要针对向下转型时所带来的安全隐患,其核心组成是在声明类或接口时,设置参数或属性的类型。

24.Java8的新特性。

1.Lambda 表达式 − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。

2.方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。
  与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
  
3.默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。

4.新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。

5.Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。

6.Date Time API − 加强对日期与时间的处理。

7.Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。

8.Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许
  我们在JVM上运行特定的javascript应用。

25.switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?

在Java1.5以前,switch(expr)中,expr只能byteshortcharint。从Java1.5开始,
Java中引入了枚举类型,expr也可以是enum类型,从Java1.7开始,expr还可以是字符串,但是
长整型在目前的版本中是不可以的。

26.在Java中,如何跳出当前的多重嵌套循环?

在最外层循环前加一个标记如A,然后用breakA;可以跳出多重循环。(Java中支持带标签的breakcontinue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用
带标签的breakcontinue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用,所以这种语法
其实不知道更好)

27.Statement和PreparedStatement有什么区别?那个性能更好?

与Statement相比
1.PreparedSatement接口代表预编译的语句,它主要的优势在于可以减少SQL的编译错误并增加SQL的安全性
  (减少SQL注射攻击的可能性)2.PreparedStatement中的SQL语句是可以带参的,避免了用字符串连接拼接SQL语句的麻烦和不安全。
3.当批量处理SQL或频繁执行相同的查询时PreparedStatement有明显的性能上的优势,
  由于数据库可以将编译优化后的SQL语句缓存起来,下次执行相同结构的语句时就会很快
  (不用再次编译和生成执行计划)

28.&和&&的区别?

&&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,
整个运算结果才为true,否则,只要有一方为false,则结果为false&&还具有短路的功能,即如果
第一个表达式为false,则不再计算第二个表达式。

29.super什么时候使用。

1.如果父类的构造函数是无参的,那子类构造函数会在第一行默认调用super().
2.如果父类没有不带参数的构造函数,或这个函数被私有化了(private修饰),必须用super显示的调用
  父类的带参构造方法。

30.说明一下public static void main(String args[])这段声明里每个关键字的作用

1.public: main方法是Java程序运行时调用的第一个方法,因此它必须对Java环境可见。
  所以可见性设置为pulic.
2.static: Java平台调用这个方法时不会创建这个类的一个实例,因此这个方法必须声明为static3.void: main方法没有返回值。
4.String是命令行传进参数的类型,args是指命令行传进的字符串数组。
拓展:如果main方法被声明为private会怎样。
     答案:能正常编译,但运行的时候会提示”main方法不是public的”。

31.sizeof 是Java 的关键字吗。

sizeof是C/C++里面的关键字,在java里不是

32.static class 与 non static class的区别

static class	
1.static修饰的是内部类,此时这个内部类变为静态内部类;对测试有用;
2.内部静态类不需要有指向外部类的引用;
3、静态类只能访问外部类的静态成员,不能访问外部类的非静态成员;

non static class
1.非静态内部类需要持有对外部类的引用;
2.非静态内部类能够访问外部类的静态和非静态成员;
3.一个非静态内部类不能脱离外部类实体被创建;
4.一个非静态内部类可以访问外部类的数据和方法;

33.char 型变量中能不能存贮一个中文汉字,为什么。

char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,
所以,char型变量中当然可以存储汉字

34.写clone()方法时,通常都有一行代码,是什么。

通常都有的一句是super.clone();
拓展:如何实现克隆。
     答案:1.实现Cloneable接口,并重写object类中的clone方法,可以实现浅克隆,也可以实现深度克隆。
          2.实现Serializable,通过对象的序列化和反序列化实现克隆,可以实现真正的深克隆。
          3.利用BeanUtils,apache和spring都提供了这个bean工具。只是他也是浅克隆。

35.构造器链是什么。

构造一个类的实例时, 将会调用沿着继承链的所有父类的构造方法。 当构造一个子类的对象时, 
子类构造方法会在完成自己的任务之前, 首先调用它的父类的构造方法。 如果父类继承自其他类, 
那么父类构造方法又会在完成自己的任务之前,调用它自己的父类的构造方法。 这个过程持续到沿着
这个继承体系结构的最后一个构造方法被调用为止。

36.我们能否重载main()方法。

main()方法也是普通方法,是可以重载的,只不过虚拟机只调用带字符串公共类型的方法。

37.SOF你遇到过哪些情况?

程序中一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过默认大小而导致溢出。
栈溢出的原因:
1.递归调用
2.大量循环或死循环
3.全局变量是否过多
4.数组、List、map数据过

38.OOM你遇到过哪些情况?你是怎么搞定的。

1.Java Heap 溢出
  java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达
  路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。
2.虚拟机栈和本地方法栈溢出
  如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。
  如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常
3.运行时常量池溢出
  异常信息:java.lang.OutOfMemoryError:PermGen space
4.方法区溢出
  方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。
  异常信息:java.lang.OutOfMemoryError:PermGen space

39.既然我们可以用RuntimeException来处理错误,那么你认为为什么Java中还存在检查型异常。

这是一个有争议的问题,在回答该问题时你应当小心。虽然他们肯定愿意听到你的观点,但其实他们
最感兴趣的还是有说服力的理由。我认为其中一个理由是,存在检查型异常是一个设计上的决定,受到了
诸如C++等比Java更早的编程语言设计经验的影响。绝大多数检查型异常位于java.io包内,这是合乎情理的,
因为在你请求了不存在的系统资源的时候,一段强壮的程序必须能够优雅的处理这种情况。通过把IOException声明
为检查型异常,Java 确保了你能够优雅的对异常进行处理。另一个可能的理由是,可以使用catchfinally来确保
数量受限的系统资源(比如文件描述符)在你使用后尽早得到释放。 Joshua Bloch编写的 Effective Java 一书
 中多处涉及到了该话题,值得一读。

40.导致空指针异常的原因。

1.对象未初始化而直接引用对象值或者方法到的
2.对象引用已经不存在或者被关闭
3.违反某些Java容器的限制,读写Null 值
4.Java8使用Optional包装null值

41.什么是异常链。

“异常链”是Java中非常流行的异常处理概念,是指在进行一个异常处理时抛出了另外一个异常,
由此产生了一个异常链条。该技术大多用于将“ 受检查异常” ( checked exception)封装成为
“非受检查异常”(unchecked exception)或者RuntimeException。顺便说一下,如果因为因为异常
你决定抛出一个新的异常,你一定要包含原有的异常,这样,处理 程序才可以通过getCause()initCause()
方法来访问异常最终的根源。

42.通过 JDBC 连接数据库有哪几种方式。

在具体访问数据库的时候,JDBC提供了两种方式:JDBC-ODBC桥接器方式和加载纯java数据库驱动程序。
拓展1:阐述 JDBC 操作数据库的基本步骤。
      答案:1. 加载驱动。
              Class.forName("oracle.jdbc.driver.OracleDriver"); 
           2. 创建连接。
              Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "tiger");
           3. 创建语句。 
              PreparedStatement ps = con.prepareStatement("select * from emp where sal between ? and ?");
              ps.setInt(1, 1000);
              ps.setInt(2, 3000);
           4. 执行语句。
              ResultSet rs = ps.executeQuery();
           5. 处理结果。
              while(rs.next()) {
              System.out.println(rs.getInt("empno") + " - " + rs.getString("ename"));
              }
           6. 关闭资源。
拓展2:JDBC 中如何进行事务处理。
      答案:Connection提供了事务处理的方法,通过调用setAutoCommit(false)可以设置手动提交事务;
      当事务完成后用commit()显式提交事务;如果在事务处理过程中发生异常则通过rollback()进行事务回滚。
      除此之外,从JDBC 3.0中还引入了Savepoint(保存点)的概念,允许通过代码设置保存点并让事务回滚到
      指定的保存点。
拓展3:使用 JDBC 操作数据库时,如何提升读取数据的性能?如何提升更新数据的性能。
      答案:1.通过结果集(ResultSet)对象的setFetchSize()方法指定每次抓取的记录数
            (典型的空间换时间策略);
           2.使用PreparedStatement语句构建批处理,将若干SQL语句置于一个批处理中执行。

43.Java中有几种类型的流。

1.字节流 InputStream/OutputStream
 ①FileInputStream/FileOutputStream:文件字节流,用于文件的读写操作
 ②BufferedInputStream/BufferedFileOutputStream:加缓冲区的字节流,用于提高效率
2.字符流 Reader/Writer
 ①FileReader/FileWriter:文件字符流,用于文本文件的读写操作
 ②BufferedReader/BufferedWriter:加缓冲区的字符流,用于提高效率
3.转换流 InputStreamReader/OutputStreamWriter
拓展1:能指定字符编码的 I/O 流类型是什么。
      答案:转换流。

44.内部类分为几种。

静态内部类,成员内部类,局部内部类,匿名内部类。
拓展1:内部类可以引用它的包含类(外部类)的成员吗。
      答案:可以。内部类是可以引用它的包含类(外部类)的成员的。   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值