2023最新面试题-Java-3

IO

1.  java IO 流分为几种?

  • 按照流的流向分,可以分为输入流和输出流;
  • 按照操作单元划分,可以划分为字节流和字符流;
  • 按照流 的角色划分为节点流和处理流。
Java Io 流共涉及 40 多个类,这些类看上去很杂乱,但实际上很有规则,而且彼 此之间存在非常紧密的联系, Java I0 流的 40 多个类都是从如下 4 个抽象类基类 中派生出来的。
  • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符 输入流。
  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输 出流。

 按操作方式分类结构图:

 IO 操作方式分类按操作对象分类结构图:

 io流第一要注意的是要用完关闭流。

2. BIO,NIO,AIO 有什么区别?

简答

  • BIOBlock IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并 发处理能力低。
  • NIONon IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
  • AIOAsynchronous IO NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO,异步 IO 的操作基于事件和回调机制。

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

  • Files. exists():检测文件路径是否存在。
  • Files. createFile():创建文件。
  • Files. createDirectory():创建文件夹。
  • Files. delete():删除一个文件或目录。
  • Files. copy():复制文件。
  • Files. move():移动文件。
  • Files. size():查看文件个数。
  • Files. read():读取文件。
  • Files. write():写入文件。

 反射

 4. 什么是反射机制?

JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个 对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 java语言的反射机制。

反射机制优缺点

优点: 运行期类型的判断,动态加载类,提高代码灵活度。
缺点: 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能 比直接的java 代码要慢很多。

5. 反射机制的应用场景有哪些?

 反射是框架设计的灵魂。

在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实 际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节码;动态代 理设计模式也采用了反射机制,还有我们日常使用的 Spring Hibernate 等框架也大量使用到了反射机 制。
举例:①我们在使用 JDBC 连接数据库时使用 Class.forName() 通过反射加载数据库的驱动程序;
           ② Spring 框架也用到很多反射机制, 经典的就是 xml 的配置模式。 Spring 通过 XML 配置模式装载 Bean 的过程:1) 将程序内所有 XML Properties 配置文件加载入内存中 ; 2)Java 类里面解析 xml 或 properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息 ; 3) 使用反射机制,根据这 个字符串获得某个类的Class 实例 ; 4) 动态配置实例的属性

5.1 反射中,Class.forNameclassloader的区别

java class.forName() classLoader 都可用来对类进行加载。
class.forName() 前者除了将类的 .class 文件加载到 jvm 中之外,还会对类进行解释, 执行类中的static 块 。 而classLoader 只干一件事情,就是将 .class 文件加载到 jvm 中,不会执行 static 中的内容 , 只有在 newInstance才会去执行 static 块。 Class.forName(name, initialize, loader)带参函数也可控制是否加载 static 块。并且只有调用了 newInstance()方法采用调用构造函数,创建类的对象

 看下Class.forName()源码

//Class.forName(String className) 这是1.8的源码
public static Class<?> forName(String className) throws
ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller),
caller);
}
//注意第二个参数,是指Class被loading后是不是必须被初始化。 不初始化就是不执行static的代
码即静态代码

 然后就是,测试代码证明上面的结论是OK的,如下:

public class Line {
static {
System.out.println("静态代码块执行:loading line");
}
}

/**
* Created by lxk on 2017/2/21
*/
public class Point {
static {
System.out.println("静态代码块执行:loading point");
}
}


public class ClassloaderAndForNameTest {
public static void main(String[] args) {
String wholeNameLine = "com.lxk.Reflect.Line";
String wholeNamePoint = "com.lxk.Reflect.Point";
System.out.println("下面是测试Classloader的效果");
testClassloader(wholeNameLine, wholeNamePoint);
System.out.println("----------------------------------");
System.out.println("下面是测试Class.forName的效果");
testForName(wholeNameLine, wholeNamePoint);
}
/**
* classloader
*/
private static void testClassloader(String wholeNameLine, String
wholeNamePoint) {
Class<?> line;

Class<?> point;
ClassLoader loader = ClassLoader.getSystemClassLoader();
try {
line = loader.loadClass(wholeNameLine);
point = loader.loadClass(wholeNamePoint);
//demo =
ClassloaderAndForNameTest.class.getClassLoader().loadClass(wholeNamePoint);//这个
也是可以的
System.out.println("line " + line.getName());
System.out.println("point " + point.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

/**
* Class.forName
*/
private static void testForName(String wholeNameLine, String wholeNamePoint)
{
try {
Class line = Class.forName(wholeNameLine);
Class point = Class.forName(wholeNamePoint);
System.out.println("line " + line.getName());
System.out.println("point " + point.getName());
} catch (Exception e) {
e.printStackTrace();
}
}



 

6.Java获取反射的

三种方法 

1.通过new对象实现反射机制
2.通过路径实现反射机制
3.通过类名实现反射机制
1 public class Student {
2 private int id;
3 String name;
4 protected boolean sex;
5 public float score;
6 }
1 public class Get {
2 //获取反射机制三种方式
3 public static void main(String[] args) throws ClassNotFoundException {
4 //方式一(通过建立对象)
5 Student stu = new Student();
6 Class classobj1 = stu.getClass();
7 System.out.println(classobj1.getName());
8 //方式二(所在通过路径-相对路径)
9 Class classobj2 = Class.forName("fanshe.Student");
10 System.out.println(classobj2.getName());
11 //方式三(通过类名)
12 Class classobj3 = Student.class;
13 System.out.println(classobj3.getName());
14 }
15 }

String相关

 7. 什么是字符串常量池?

 字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存 储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回 它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。

类型信息(元数据信息)等其他信息被移动到了元空间中;

但是运行时常量池和字符串常量池被移动到了堆中。

1.8

 8. String 是最基本的数据类型吗

不是。 Java 中的基本数据类型只有 8 个 : byte short int long float double char
boolean;不包括 String。
演变:
char 类型的变量,也就是一个 char 类型数组,比如 你好 就是长度为 2 的数组 char[] chars = {‘ ’,‘ ’}; 但是使用数组过于麻烦,所以就有了 String String 底层就是一个 char 类型的数组,只是使用的时候开 发者不需要直接操作底层数组,用更加简便的方式即可完成对字符串的使用。
1 /** The value is used for character storage. */
2 private final char value[];

所以String是不可变的?底层存储是不可变的char数组。

9. String有哪些特性

  • 不变性:String 是只读字符串,是一个典型的 immutable 对象,对它进行任何操作,其实都是创 建一个新的对象,再把引用指向该对象。不变模式的主要作用在于当一个对象需要被多线程共享并 频繁访问时,可以保证数据的一致性。
  • 常量池优化:String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时, 会直接返回缓存的引用。
  • final:使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性。

 10 String str="i"与 String str=new String(“i”)一样吗?

不一样,因为内存的分配方式不一样。String  str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存 中。 String s = new String(“xyz”);创建了几个字符串对象两个对象,一个是静态区的"xyz",一个是用 new创建在堆上的对象。

1 String str1 = "hello"; //str1指向静态区
2 String str2 = new String("hello"); //str2指向堆上的对象
3 String str3 = "hello";
4 String str4 = new String("hello");
5 System.out.println(str1.equals(str2)); //true
6 System.out.println(str2.equals(str4)); //true
7 System.out.println(str1 == str3); //true
8 System.out.println(str1 == str2); //false
9 System.out.println(str2 == str4); //false
10 System.out.println(str2 == "hello"); //false
11 str2 = str1;
12 System.out.println(str2 == "hello"); //true

字符串反转

StringBuffer stringBuffer = new StringBuffer();
stringBuffer. append("abcdefg");
System. out. println(stringBuffer. reverse());

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

  • indexOf():返回指定字符的索引。
  • charAt():返回指定索引处的字符。
  • replace():字符串替换。
  • trim():去除字符串两端空白。
  • split():分割字符串,返回一个分割后的字符串数组。
  • getBytes():返回字符串的 byte 类型数组。
  • length():返回字符串长度。
  • toLowerCase():将字符串转成小写字母。
  • toUpperCase():将字符串转成大写字符。
  • substring():截取字符串。
  • equals():字符串比较

12. 在使用 HashMap 的时候,用 String key 有什么好处?

HashMap 内部实现是通过 key hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以 当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。

13. StringStringBufferStringBuilder的区别是什么?

 可变性

String 类中使用字符数组保存字符串, private final char value[] ,所以 string 对象是不可变的。
StringBuilder StringBuffer都继承自AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串, char[] value, 两种对象都是可变的。

线程安全性

 AbstractStringBuilder是StringBuilderStringBuffer的公共父类,定义了一些字符串的基本操作,如 expandCapacity、appendinsertindexOf等公共方法。StringBuffer对方法加了同步锁或者对调用 的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全 的。

性能

对于三者使用的总结
如果要操作少量的数据用 = String 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder 多线程操 作字符串缓冲区 下操作大量数据 = StringBuffer

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值