Bootstrap

java面试-java基础(终)


一、int和Integer有什么区别?

  • integer是int的包装类,属于引用数据类型,而int是Java的基本数据类型
  • Integer默认值是null,int的默认值是0
  • Integer是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
  • Integer变量必须实例化后才可以使用,而int不需要。

二、==比较Integer、new Integer、int的值

除以下情况外,==比较都是true

  • new Integer(100) != new Integer(100) 因为new生成的两个integer指向堆中的地址,而引用数据类型比较时实际是比较地址是否相同。
  • new Integer(100) != Integer i=100 因为非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象
  • Integer i = 128 != Integer j=128(Integer缓存-128-127的Integer对象,自动装箱时不会new新的Integer对象,而是直接引用缓存池中的Integer对象)

三、String转成Integer原理?

  • String转成Integer使用的方法:
Integer.parseInt(String s)
Integer.valueOf(String s)
  • 最终调用Integer类中的parseInt(String s, int radix)方法,字符串遍历计算负的值累减,1314=-1 * (-1±310±1100)

四、Error和Exception的区别?

异常体系

  • 受检异常:编译器会检查并要求必须处理的异常。
  • 非受检异常:编译器不会检查也不要求必须处理的异常.
  • Throwable:所有错误或异常的超类,表示程序中可能会产生的异常
    • Error(非受检异常)系统级的错误;运行环境中的内部错误或者硬件问题,会导致应用程序中断.如:系统崩溃、虚拟机错误、内存空间不足、方法调用栈溢出等
    • Exception:程序可以处理的异常
      • 编译期异常Checked Exception(受检异常)Exception中除RuntimeException及其子类之外的异常。通常不会自定义该类异常,而是直接使用系统提供的异常类。
      • 运行时期异常RuntimeException及其子类异常(非受检异常),出现原因大多因为代码本身有问题应该从逻辑上去解决并改进代码

五、异常的处理方式?

  • throw,throws抛出,自己不处理,抛给调用者处理(throws异常类用在方法上,可以跟多个异常类;throw异常对象用在方法内)
  • try catch捕获异常;可选择加上finally语句块,finally 语句块不管程序是否正常执行,最终它都会必然执行。

六、什么是java IO?

  • 输入输出是相对于内存的,加载进入内存的叫输入流、反之为输出流
  • InputStream/Reader: 所有输入流的基类,前者是字节输入流,后者是字符输入流。
  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

七、InputStream为什么不能重复读取?如何实现重复读取?

  • 因为inputStream设计就是这样的
  • 使用ByteArrayOutputStream
public class InputStreamCacher {  
    private ByteArrayOutputStream byteArrayOutputStream = null;
    public InputStreamCacher(InputStream inputStream) {
        byteArrayOutputStream = new ByteArrayOutputStream();  
        byte[] buffer = new byte[1024];    
        int len;    
        try {  
            while ((len = inputStream.read(buffer)) > -1 ) {    
                byteArrayOutputStream.write(buffer, 0, len);    
            }  
            byteArrayOutputStream.flush();  
        } catch (IOException e) {  
            logger.error(e.getMessage(), e);  
        }    
    }
    public InputStream getInputStream() { 
        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());  
    }  
}  
InputStreamCacher  cacher = new InputStreamCacher(inputStream);  
InputStream stream = cacher.getInputStream();

八、字节流和字符流区别?

  • Java用Unicode编码存储字符
  • 其实字符流是由 Java 虚拟机将字节转换得到的,为了方便在不知道编码的情况下操作字符,提高读写效率
  • 字节流按8位传输(操作字节和字节数组、数字_)以字节为单位输入输出数据
  • 字符流按16位传输(由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的)对多国语言支持性比较好
  • 音频文件、图片、歌曲使用用字节流,中文文本的,使用字符流
  • 不管文件读写还是网络发送接收,信息的最小存储单元都是字节

九、BIO,NIO,AIO 区别

  • BIO(Block IO):同步阻塞。服务器实现模式为一个连接一个线程
  • NIO(non-blocking IO)同步非阻塞。服务器实现模式为一个IO请求一个线程
  • AIO(Asynchronous I/O)异步不阻塞。服务器实现模式为一个有效请求一个线程

十、什么是序列化和反序列化?怎么序列化?

  • 序列化 (Serialization)把Java对象转为二进制流,方便存储和传输.反序列化就是把二进制流恢复成对象。
  • 序列化方法:
    • Java对象序列化:通过对象输出流ObjectOutputStream和对象输入流ObjectInputStream。
    • Json序列化:使用jackson包,通过ObjectMapper类操作,比如将对象转化为byte数组或者将json串转化为对象

十一、什么是零拷贝?

  • 在应用程序不对数据做修改前提下,减少从内核缓冲区到用户缓冲区,再从用户缓冲区到内核缓冲区两次数据拷贝(需要CPU参与)和用户态与内核态的两次切换,直接在内核态完成数据拷贝
  • 实现拷贝方法:mmap+write(RocketMQ),sendfile(Kafa),
  • mmap将内核中读缓冲区地址与用户空间缓冲区地址进行映射。效果是将读写2个CPU拷贝改为1个内核缓冲区到socket缓冲区的CPU拷贝**
  • sendfile方式,效果是少了(读数据时内核到用户和写数据时用户到内核)2次状态切换和将读写2个CPU拷贝改为1个内核缓冲区到socket缓冲区的CPU拷贝

十二、泛型和类型擦除原理?

  • 泛型(generics)提供了编译时类型安全检测机制,本质是参数化类型,所操作的数据类型被指定为一个参数。
  • 好处是编译时检查类型安全,并且所有的强制转换都是自动和隐式的,不需要使用显式转换和instanceOf操作符,提高代码重用率
  • 泛型擦除是指编译器在编译时擦擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息
  • 为什么需要泛型擦除?为了向下兼容

十三、List中泛型的区别?

  • List<? extends T>接受任何继承自T的类型的List
  • List<? super T>接受任何T的父类构成的List

总结

本文介绍了的Java面试-java基础(终),如有问题欢迎私信和评论

;