Java基础面试题附带答案(八)

2023-10-30

106字节流和字符流的区别?

1)字节流读取的时候,读到一个字节就返回一个字节;字符流读取的时候会读到一个或多个字节(这个要根据字符流中编码设置,一般中文对应的字节数是两个,在UTF-8码表中是3个字节)

2)字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。

3)字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。

案例1:在写操作的过程中,没有关闭字节流操作,但是文件中也依然存在了输出的内容代码如下:

public static void main(String[] args) throws Exception { 
    // 第1步:使用File类找到一个文件 
    File f = new File("d:" + File.separator + "test.txt"); // 声明File 对象 
    // 第2步:通过子类实例化父类对象 
    OutputStream out = new FileOutputStream(f); 
    // 第3步:进行写操作 
    String str = "Hello World!!!"; // 准备一个字符串 
    byte b[] = str.getBytes(); // 字符串转byte数组 
    out.write(b); // 将内容输出 
    // 第4步:关闭输出流 
    // out.close();
}

案例2:在写操作的过程中,没有关闭字符流操作,发现文件中没有任何内容输出。代码如下:

public static void main(String[] args) throws Exception {         
    // 第1步:使用File类找到一个文件    
    File f = new File("d:" + File.separator + "test.txt");// 声明File 对象    
    // 第2步:通过子类实例化父类对象    
    Writer out = new FileWriter(f);            
    // 第3步:进行写操作    
    String str = "Hello World!!!"; // 准备一个字符串    
    out.write(str); // 将内容输出
    out.flush();     
    // 第4步:关闭输出流    
    // out.close();  
}  

这是因为字符流操作时使用了缓冲区,而在关闭字符流时会强制性地将缓冲区中的内容进行输出,但是如果程序没有关闭,则缓冲区中的内容是无法输出的。当然如果在不关闭字符流的情况下也可以使用Writer类中的flush()强制性的清空缓存,从而将字符流的内容全部输出。

107怎么样把字节流转换成字符流,说出它的步骤?

解题思路:把字节流转成字符流就要用到适配器模式,需要用到OutputStreamWriter。它继承了Writer接口,但要创建它必须在构造函数中传入一个OutputStream的实例,OutputStreamWriter的作用也就是将OutputStream适配到Writer。它实现了Reader接口,并且持有了InputStream的引用。利用转换流OutputStreamWriter.创建一个字节流对象,将其作为参数传入转换流OutputStreamWriter中得到字符流对象.

108什么是序列化?

序列化是指把对象转换为字节序列的过程,序列化后的字节流保存了对象的状态以及相关的描述信息,从而方便在网络上传输或者保存在本地文件中,达到对象状态的保存与重建的目的。

反序列化:客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。

序列化的优势:一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。三是通过序列化在进程间传递对象;

109IO如何实现序列化和反序列化?

(1)java.io.ObjectOutputStream:表示对象输出流;它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中;

(2)java.io.ObjectInputStream:表示对象输入流;它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回;

注意:只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常!

序列化和反序列化的示例

public class SerialDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //序列化
        FileOutputStream fos = new FileOutputStream("object.out");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        User user1 = new User("xuliugen", "123456", "male");
        oos.writeObject(user1);
        oos.flush();
        oos.close();
        //反序列化
        FileInputStream fis = new FileInputStream("object.out");
        ObjectInputStream ois = new ObjectInputStream(fis);
        User user2 = (User) ois.readObject();
        System.out.println(user2.getUserName()+ " " + 
        user2.getPassword() + " " + user2.getSex());
        //反序列化的输出结果为:xuliugen 123456 male
    }
}
public class User implements Serializable {
    private String userName;
    private String password;
    private String sex;
    //全参构造方法、get和set方法省略
}

110PrintStream、BufferedWriter、PrintWriter 的比较?

1. PrintStream 类的输出功能非常强大,通常如果需要输出文本内容,都应该将输出流包装成PrintStream 后进行输出。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream

2.BufferedWriter:将文本写入字符输出流,缓冲各个字符从而提供单个字符,数组和字符串的高效写入。通过 write()方法可以将获取到的字符输出,然后通过 newLine()进行换行操作。BufferedWriter 中的字符流必须通过调用 flush 方法才能将其刷出去。并且 BufferedWriter 只能对字符流进行操作。如果要对字节流操作,则使用 BufferedInputStream

3.PrintWriter 的 println 方法自动添加换行,不会抛异常,若关心异常,需要调用 checkError方法看是否有异常发生,PrintWriter 构造方法可指定参数,实现自动刷新缓存(autoflush)。

111如果我要对字节流进行大量的从硬盘读取,要用那个流,为什么?

因为明确说了是对字节流的读取,所以肯定是InputStream或者他的子类,又因为要大量读取,肯定要考虑到高效的问题,自然想到缓冲流BufferedInputStream。

原因:BufferedInputStream是InputStream的缓冲流,使用它可以防止每次读取数据时进行实际的写操作,代表着使用缓冲区。不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!并且也可以减少对磁盘的损伤。

112什么是集合?

集合就是一个放数据的容器,准确的说是放数据对象引用的容器;集合类存放的都是对象的引用,而不是对象的本身;集合类型主要有3种:set(集)、list(列表)和map(映射)。

113集合框架中的泛型有什么优点?

Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。它也给运行时带来好处,因为不会产生类型检查的字节码指令。

114Iterator是什么?

Iterator接口提供遍历任何Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例。迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者在迭代过程中移除元素。

115集合和数组的区别?

数组是固定长度的;集合可变长度的。

数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。

数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。

116常用的集合类有哪些?

Map接口和Collection接口是所有集合框架的父接口:

Collection接口的子接口包括:Set接口和List接口

Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等

Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等

List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等

117Collection 和 Collections 有什么区别?

java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。

Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。

118Set和List的区别?

Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。都可以存储null值,但是set不能重复所以最多只能有一个空元素。

Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。

List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。

119Arraylist与 LinkedList 异同?

1)Arraylist 底层使用的是Object数组;LinkedList 底层使用的是双向循环链表数据结构;

2)ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。插入末尾还好,如果是中间,则(add(int index, E element))接近O(n);LinkedList 采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响,都是近似 O(1)而数组为近似 O(n)。对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。

3)LinkedList 不支持高效的随机元素访问,而ArrayList 实现了RandmoAccess 接口,所以有随机访问功能。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。所以ArrayList随机访问快,插入慢;LinkedList随机访问慢,插入快。

4)ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。

120ArrayList和Vector有何异同点?

ArrayList和Vector在很多时候都很类似。

(1)两者都是基于索引的,内部由一个数组支持。

(2)两者维护插入的顺序,我们可以根据插入顺序来获取元素。

(3)ArrayList和Vector的迭代器实现都是fail-fast的。

(4)ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。

以下是ArrayList和Vector的不同点。

(1)Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。

(2)ArrayList比Vector快,它因为有同步,不会过载。

(3)ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java基础面试题附带答案(八) 的相关文章

随机推荐

  • 计算机网络(一)----概述

    概述 功能 组成 分类 性能指标 一 计算机网络的概述 1 网络的概念网络是由若干结点和链路组成 结点可以是计算机 集线器 交换机 路由器等 链路可以是有线链路或无线链路 如电信网络 电话 电报 传真服务 有限电视网络 观看电视节目 计算机
  • C++矩阵运算类(Matrix.h)

    这个类数据类型是double 包含了常用的矩阵计算 多数方法经过实践验证 也难免有不足之处 如有发现欢迎指出 https github com ims0 comTutor tree master matrix include
  • 晶振的负载电容与外接电容的区别与关系

    经常遇到有人把晶振的负载电容与外接电容混淆 甚至还有人误以为这是指同样的参数 这里需要特别指出的是 若你这样想 就大错特错了 下面就为您进行分析与区分 负载电容指的是晶振的一个内部重要电气参数 一般情况下 对功耗不太敏感的电子设备PCBA上
  • Stable Diffusion模型阅读笔记

    Stable Diffusion模型 什么是Stable Diffusion模型 一般而言 扩散是在图像中反复添加小且随机的噪声 与之相反 Stable Diffusion模型是一种将噪声生成为图像的机器学习模型 经过训练 它可逐步对随机高
  • leetcode 链表相交

    面试题 02 07 链表相交 力扣 LeetCode leetcode cn com 在看别人的题解之前我有过两个思路 1 最容易想到的就是对链表A中的每个元素都在B中查找 如果找到了就是相交点 显然这种方法的时间复杂度比较高 leetco
  • 闲鱼新手如何快速卖货 咸鱼赚钱排名优化技巧

    闲鱼现在很多人都有了解 对于高价值自己没用的二手物品 甚至全新物品在这个平台出售 闲鱼 对于大多数人来说只是一个卖二手和买二手的app 哪里有人 哪里就有流量 哪里有流量 哪里就存在引流的空间 小满老师介绍以下八个方法 供大家学习 teac
  • Spring三种bean注入方式

    Spring中依赖注入有三种注入方式 一 构造器注入 二 设值注入 setter方式注入 三 Feild方式注入 注解方式注入 一 构造器注入 构造器注入顾名思义就是在程序组件中实现构造器 构造器可以是一个也可以是多个 废话不多说 直接上代
  • flex 子元素占满剩余高度 与 flex:1 的子元素 overflow:hidden 失效

    这几天使用flex开发大屏 遇到一个印象比较深的问题就是flex的子元素 在其他兄弟元素的高度不定的情况下 如何占满父元素的剩余空间 效果图 要点就是 1 父元素要设置 display flex 2 父元素的主轴方向设置为从上到下 flex
  • Dockerfile 中 ENTRYPOINT 的使用

    先占个坑 以免忘记 有空了来填
  • 2、Java基础-NIO、IO、ThreadLocal类

    1 IO和NIO 1 1 传统IO和NIO区别在哪 Java NIO和IO之间最大的区别在 IO是面向流的 而NIO是面向缓存区buffer的 Java NIO是非阻塞式的 意味着使用一个线程向某通道发送一个请求读取数据 如果buffer中
  • Squid日志分析与访问控制详解

    squid日志分析与访问控制 squid的日志系统能够帮助我们查看访问者的记录 包括来访者Internet的站点信息 时间占用信息 排名 连接次数和访问量 是一个很完善的日志系统 squid常用日志分为如下两个 分别是access log
  • 笔试题14:用TCP通信模型创建一个Web服务器(源码)

    我们都知道 IIS Apache和tomcat等Web服务器可以用来创建Web站点 负责接受客户端浏览器的HTTP请求 那么 他们是如何实现的呢 其实基本原理是采用TCP通信模型 下面给出一个采用Java的TCP编程API创建的简易Web服
  • deque容器和list容器学习

    1 deque简介 deque容器同样是一种顺序容器 你可以了解你的元素的存储位置 你可以安排你的元素的存储位置 和vector相比 deque可以实现用常数的时间在容器头部插入元素 同样deque也没有容量的概念 这是因为deque可以动
  • AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy

    使用tf distribute MirroredStrategy 时 出现警告 AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE
  • MySQL 8.0.23中复制架构从节点自动故障转移

    接触MGR有一段时间了 MySQL 8 0 23的到来 基于MySQL Group Replicaion MGR 的高可用架构又提供了新的架构思路 灾备机房的slave 如何更好的支持主机房的MGR MGR 到底可以坏几个节点 这次我就以上
  • fastgithub

    之前我在网上搜过解决办法 其中一个是修改 hosts 文件 但是效果不太理想 我在这里给大家推荐github上的一个开源项目 FastGithub 用了这个之后 效果就比较理想了 次次都能访问到 源码地址 GitHub dotnetcore
  • 简易虚拟培训系统-UI控件的应用2

    目录 Text组件 文字显示 Text组件 文字动态显示 ScrollView组件 使用文件流动态读取硬盘文件 本篇介绍Text和ScrollView的简单应用 以及读取硬盘中 txt文本的内容 Text组件 文字显示 1 加入Text 在
  • 小程序导入npm包 注意事项

    官方api https developers weixin qq com miniprogram dev devtools npm html 1 需要在小程序文件夹 npm init 2 安装需要的npm包 先安装需要的npm 包在构建np
  • 解释器与编译器区别

    让我们看看编译器和解释器之间的主要区别 1 编译器将一个程序作为一个整体进行翻译 而解释器则一条一条地翻译一个程序 2 在编译器的情况下生成中间代码或目标代码 而解释器不创建中间代码 3 编译器比解释器要快得多 因为编译器一次完成整个程序
  • Java基础面试题附带答案(八)

    106字节流和字符流的区别 1 字节流读取的时候 读到一个字节就返回一个字节 字符流读取的时候会读到一个或多个字节 这个要根据字符流中编码设置 一般中文对应的字节数是两个 在UTF 8码表中是3个字节 2 字节流可以处理所有类型数据 如 图