1. java基础
1.线程和进程的区别
-
根本区别:进程是资源分配最小单位,线程是程序执行的最小单位。 计算机在执行程序时,会为程序创建相应的进程,进行资源分配时,是以进程为单位进行相应的分配。每个进程都有相应的线程,在执行程序时,实际上是执行相应的一系列线程。
-
地址空间:进程有自己独立的地址空间,每启动一个进程,系统都会为其分配地址空间,建立数据表来维护代码段、堆栈段和数据段;线程没有独立的地址空间,同一进程的线程共享本进程的地址空间。
-
资源拥有:进程之间的资源是独立的;同一进程内的线程共享本进程的资源。
-
执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
-
线程是处理机调度的基本单位,但是进程不是。由于程序执行的过程其实是执行具体的线程,那么处理机处理的也是程序相应的线程,所以处理机调度的基本单位是线程。
-
系统开销:进程执行开销大,线程执行开销小。
2.stringBulider和stringBuffer的区别及使用
-
StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,
-
只是StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。
-
在单线程程序下,StringBuilder效率更快,因为它不需要加锁,不具备多线程安全而StringBuffer则每次都需要判断锁,效率相对更低
3.final 在 java 中有什么作用?
- final 修饰的类叫最终类,该类不能被继承
- final 修饰的方法不能被重写。
- final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
4.java 中操作字符串都有哪些类?它们之间有什么区别?
操作字符串的类有:String、StringBuffer、StringBuilder。String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。
5.BIO、NIO、AIO 有什么区别?
- BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
- NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
- AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
6.进程之间的通信方式
-
管道
它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)
-
FIFO
FIFO可以在无关的进程之间交换数据,与无名管道不同。FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。
-
信号量
它是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。
信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。 -
消息队列
消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
-
共享内存
共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区。
7.java的容器有哪些
8.Collection 和 Collections 有什么区别?
- java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。
- Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。
9.List、Set、Map 之间的区别是什么?
10.HashMap 和 Hashtable 有什么区别?
- hashMap去掉了HashTable 的contains方法,但是加上了containsValue()
- containsKey()方法。
- hashTable同步的,而HashMap是非同步的,效率上比hashTable要高。
- hashMap允许空键值,而hashTable不允许。
- hashmap是非线程安全的,hashtable是线程安全的
从源码分析hashmap为何允许空键值,而hashTable不行:
hashmap源码:
HashMap在put的时候会调用hash()方法来计算key的hashcode值,可以从hash算法中看出当key==null时返回的值为0。因此key为null时,hash算法返回值为0,不会调用key的hashcode方法。
hashtable源码:
上面可以看出当HashTable存入的value为null时,抛出NullPointerException异常。如果value不为null,而key为空,在执行到int hash = key.hashCode()时同样会抛出NullPointerException异常
11.如何决定使用 HashMap 还是 TreeMap?
对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。
12.说一下 HashMap 的实现原理?
HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。当我们往Hashmap中put元素时,首先根据key的hashcode重新计算hash值,根绝hash值得到这个元素在数组中的位置(下标),如果该数组在该位置上已经存放了其他元素,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放入链尾.如果数组中该位置没有元素,就直接将该元素放到数组的该位置上。
需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)
13.ArrayList 和 Vector 的区别是什么?
- Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
- ArrayList比Vector快,它因为有同步,不会过载。
- ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。
14.什么是反射?
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力
Java反射:在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?
对于任意一个对象,能否调用它的任意一个方法Java反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。在运行时判断任意一个类所具有的成员变量和方法。
在运行时调用任意一个对象的方法。
15.final finally finalize区别
- final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
- finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
- finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。
16.集合和数组的区别
- 数组是固定长度的;集合可变长度的。数组可以存储基本数据类型,也可以存储引用数据类型;
- 集合只能存储引用数据类型。数组存储的元素必须是同一个数据类型;
- 集合存储的对象可以是不同数据类型。
17.常用的集合类有哪些?
Map接口和Collection接口是所有集合框架的父接口:
-
Collection接口的子接口包括:Set接口和List接口
-
Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
-
Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
-
List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
18.什么是 Java 序列化和反序列化,如何实现 Java 序列化?
序列化:指把数据从内存中持久化到硬盘上或者其它存储设备中。
反序列化:指把数据从硬盘或者其它存储设备加载到内存中。
实现java序列化:使用ObjectOutPutStream对象的writeObject(Object obj)方法就可以将obj对象保存到硬盘上。
实现反序列化:使用ObjectOutPutStream对象的readeObject()方法就可以将obj对象从硬盘上恢复到内存中且状态也恢复。
19.线程安全的list有哪些?
- Vector
- java.util.Collections.SynchronizedList
- java.util.concurrent.CopyOnWriteArrayList
20.String对象两种创建方法的区别
执行语句String str1=new String(“abc”)时,不管"String常量池"中是否存在字符串"abc",直接在堆内存中新建一个字符串"abc",然后将其赋给str1, 并且在"String常量池"中创建"abc",故第一种方法共创建了2个对象(一个在堆内存上,一个在"String常量池"上)和一个引用变量。
执行语句String str2=“abc"时,首先查看"String常量池"中是否存在字符串"abc”,如果存在则直接将"abc"赋给str2,如果不存在则先 在"String常量池"中新建一个字符串"abc",然后再将其赋给str2。 所以两种初始化的方法的区别是第一种方法不仅会在堆内存上建立相应的对象,还会在一块特殊的内存区域建立相应的对象,而第二种方法只在特殊的内存区域(“String常量池”)建String对象。
21.string类的常用方法
22.面向对象的四大特征是什么?
多态、继承、封装、抽象
-
多态:多态性是指允许相同或不同子类型的对象对同一消息作出不同响应
重载:同一个动作作用在同一个对象上拥有不同的解释 overload重载又称静态多态,编译时多态
重写:同一个动作作用在不同的对象上拥有不同的解释 override
-
继承:继承是从已有类得到继承信息创建新类的过程
-
封装:封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。就是把能隐藏的东西隐藏起来,只向外提供使用的接口
-
抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面,抽象只关注对象的哪些属性和行为,并不关注这此行为的细节是什么
23.抽象类和接口的区别是什么?
抽象类:
抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。
抽象类就是为了继承而存在的
如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
接口:
接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法
区别:
- 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型;
- 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
24.重载和重写的区别
重写:
在方法名,参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对方法体进行修改或重写
重载:
同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。