Java工程师面试1000题41-50

41、什么是Java序列化?如何实现Java序列化?

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,可以对流化后的对象进行读写操作,也可以将流化后的对象传输与网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题

序列化就是把Java对象转为字节序列的过程反序列化就是把字节序列恢复为Java对象的过程。对象序列化主要有两种用途:第一是把对象的字节序列保存到硬盘上,通常存放在一个文件中;再有一个作用就是在网络中传送对象的字节序列

当两个进程再进行远程通信的时候,彼此间可以发送各种类型的数据。无论何种类型的数据,都会以二进制序列的形式在网络上传送,发送方需要把把这个Java对象转换为字节序列,在可以在网络上传送,接收方需要把字节序列恢复为Java对象

实现序列化,需要将该类实现Serializable接口,该接口没有要实现的方法,实现Serializable接口只是为了标注该对象是可被序列化的,然后使用一个输出流(例如FileOutPutStream)来构造一个ObjectOutputStream(对象流)对象,接着使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则使用输入流。

42、字节流和字符流的区别?

字节流读取的时候,读到一个字节就返回一个字节字符流使用了字节流读到一个或者多个字节时(中文对应的字节数是两个,在UTF-8码表中是三个字节),首先去查指定的编码表将查到的字符返回字节流可以处理所有类型数据,包括图片、MP3、视频文件等,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都要使用字节流。字节流主要是操作byte类型数据以byte数组为准,主要操作类就是OutputStream和InputStream

字符流处理的单元为2个字节的Unicode字符,分别操作字符字符数组或者字符串,而字节流处理单元为1个字节操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而构成的,他对多国语言的支持性比较好。在程序中**,一个字符等于2个字节**,Java提供了Reader、Writer两个专门操作字符流的类

字节输入流转字符输入流通过InputStreamReader实现,该类的构造函数可以传入InputStream对象;同理,字节输出流转字符输出流通过OutputStreamWriter实现,该类的构造函数可以传入OutputStream对象

43、如何实现对象的克隆?

实现对象的克隆有两种方式:第一是实现Cloneable接口,并重写Object类中的clone()方法;第二种是实现Serializable接口,通过对象的序列化和反序列化实现真正的深度克隆。

基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种方式明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总好过在运行时才出现!

44、ArrayList、HashSet、HashMap是线程安全的吗?

以上三个集合的每个方法都没有加锁,显然不是线程安全的。在集合中,Vector和HashTable是线程安全的,它们把各自核心代码方法上都添加了synchronized关键字。Collections工具类提供了相关API,可以将ArrayList、HashSet、HashMap这三个线程不安全的集合变为安全的,如下所示:

Collections.synchronizedCollection©
Collections.synchronizedList(list)
Collections.synchronizedMap(map)
Collections.synchronizedSet(set)
上面几个函数都有对应的返回值,传入什么类型返回什么类型,查看源码其实很简单,就是将集合的核心方法上都添加了synchronized关键字。

45、简要叙述一下List三个子类各自的特点。

ArrayList:底层结构使用数组实现,便于索引,查询速度快,但增加和删除操作慢

LinkedList:底层是使用链表数据结构实现的,链表内存是散乱的,**每一个元素存储本身内存地址的同时还存储下一个元素的地址;**增删操作快,查询慢

Voctor:底层使用数组实现,由于是使用了synchronized关键字,是线程安全的,故效率也偏低

46、简要叙述一下Map接口四个子类各自的特点。

HashMap:根据键的hashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为null,不允许多条记录的值为null。HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要同步,可以用Collections.synchronizedMap(HashMap map)方法使HashMap具有同步的能力。

Hashtable:HashMap类似,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,然而,这也导致了Hashtable在写入时会比较慢。

LinkedHashMap:保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的。在遍历的时候会比HashMap慢。有HashMap的全部特性。

TreeMap:能够把它保存的记录根据键排序默认是按升序排序,也可以指定排序的比较器。当用Iteraor遍历TreeMap时,得到的记录是排过序的。TreeMap的键和值都不能为空。

47、简要叙述一下Set接口两个实现类的各自特点。

HashSet:HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。HashSet不能保证元素的排列顺序,不是线程安全的,集合元素可以是 null。当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。

LinkedHashSet:LinkedHashSet 是 HashSet 的子类,LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的,插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。基于LinkedHashMap来进行实现。

TreeSet:TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。TreeSet 两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。向TreeSet中添加的元素必须是同一个类型的。

48、简述一下List和Map、Set之间的区别及集合的选用。

List和Set都是存储单列数据的集合,Map是存储键和值这样的双列数据的集合List中存储的数据有顺序的,并且允许重复Set中存储的数据是无序的,且不允许有重复,元素在集合中的位置是由元素的hashCode决定的,所以位置是固定的,但是位置却不是用户可以控制的,所以对用户来说,Set中的元素还是无序的;Map中存储的元素是没有顺序的,其键是不能重复的,但是它的值却是可以重复的。

集合的选用主要根据集合的特点来选用,比如我们需要根据键值获取到元素值时就选用Map接口下的集合,**需要排序时选择TreeMap,****不需要排序时就选择HashMap,**需要保证线程安全就选用ConcurrentHashMap.当我们只需要存放元素值时,就选择实现Collection接口的集合,需要保证元素唯一时选择实现Set接口的集合比如TreeSet或HashSet,不需要就选择实现List接口的比如ArrayList或LinkedList,然后再根据实现这些接口的集合的特点来选用。

49、说一下 ConcurrentHashMap 。

ConcurrentHashMap对整个桶数组进行了分割分段(Segment),具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。然后在每一个分段上都用lock锁进行保护,相对于HashTable的synchronized锁的粒度更精细了一些,并发性能更好。JDK1.8之后ConcurrentHashMap启用了一种全新的方式实现,利用了CAS算法。

(注:ConcurrentHashMap 后面还会再提到,在这里只是简单提一下)

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

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

原文:https://blog.csdn.net/qq_21583077/article/details/88252440

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值