成为Java顶尖程序员,先过了下面问题!(二)
二、Java基础
1.接口与抽象类的区别?
- 接口是抽象方法的集合,一个类实现了某个接口,就必须实现接口中的所有方法。
- 抽象类是用来描述子类的通用特性的,不能被实例化,只能作为子类的超类。
各项差异对比:
参数 | 抽象类 | 接口 |
---|---|---|
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的。它根本不存在方法的实现 |
实现 | 子类使用extends 关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 |
子类使用关键字implements 来实现接口。它需要提供接口中所有声明的方法的实现 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
与普通Java类的区别 | 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 | 接口是完全不同的类型 |
访问修饰符 | 抽象方法可以有public 、protected 和default 这些修饰符 |
接口方法默认修饰符是public 。你不可以使用其它修饰符。 |
main方法 | 抽象方法可以有main方法并且我们可以运行它 | 接口没有main方法,因此我们不能运行它。 |
多继承 | 抽象方法可以继承一个类和实现多个接口 | 接口只可以继承一个或多个其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 | 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 | 如果你往接口中添加方法,那么你必须改变实现该接口的类。 |
2.Java中的异常有哪几类?分别怎么使用?
Java的异常分为两大类:Checked异常和Runtime异常(运行时异常)。所有的RuntimeException类及其子类的实例被称为Runtime异常,不是RuntimeException或其子类的异常实例则被称为Checked异常。
常见的Checked异常有:IOException, SQLException
常见的Runtime异常有:ArithmeticException, ClassCastException, IllegalArgumentException, NullPointerException
3.常用的集合类有哪些?比如List如何排序?
Java集合类主要从两个接口派生而出:Collection
和Map
。
Collection
又派生出Set
,Queue
和List
三个重要接口。常用实现类有,HashSet
,LinkedHashSet
,TreeSet
(采用红黑树数据结构),EnumSet
(专门用于存放枚举变量的Set); ArrayList
(以数组结构),LinkedList
(以链表结构),Vector
(不建议使用), Stack
(不建议使用); PriorityQueue
,ArrayDeque
;
Map
的常见实现类有HashMap
,LinkedHashMap
,TreeMap
,EnumMap
,Hashtable
(不建议使用)
对List排序可以采用 Collections.sort(arr)
4.ArrayList和LinkedList内部的实现大致是怎样的?他们之间的区别和优缺点?
ArrayList
内部采用数组的方式实现,LinkedList
内部采用链表的方式实现。由于数组以一块连续内存区域来保存所有的数组元素,所以数组在随机访问时性能最好,即如果访问的频率远高于插入和删除时,应选用ArrayList
。如果插入和删除的频率远高于访问,那么应该选用LinkedList
。
5.内存溢出是怎么回事?请举一个例子?
计算机内存分配不够用了。比如递归函数没有写跳出,就会出现栈内存溢出。
6.==和equals的区别?
- 使用==比较原生类型如:boolean、int、char等等,使用equals()比较对象。
- ==返回true如果两个引用指向相同的对象,equals()的返回结果依赖于具体业务实现
- 字符串的对比使用equals()代替==操作符
7.hashCode方法的作用?
- equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
- hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
所有对于需要大量并且快速的对比的话如果都用equal()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),如果hashCode()相同,此时再对比他们的equal(),如果equal()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!
这种大量的并且快速的对象对比一般使用的hash容器中,比如HashSet
,HashMap
,Hashtable
等等
8.NIO是什么?适用于何种场景?
简而言之,io是面向流的,是就用多少拿多少。是阻塞的。数据量不大的或者不在意阻塞的时可以用。nio是面向块的,先把数据搬过来,先存到缓存区里面,如果线程要用从缓存区拿。所以线程不需要时刻盯着io了,可以先做一些其他的事情,过几天再来看一下缓存。是同步非阻塞的。因此,nio里有Buffer类作为缓冲区,Channel(通道)相当于io里的steam的抽象,Selector是nio提供的管理多个Channel的工具。nio出现也是因为io渐渐成为一些程序速度的瓶颈。
aio加了一个异步的特性。当我们要拿数据花费时间太长的时候,我们可以考虑使用异步的io。异步就是可以理解为,让io先处理着,我线程先去干别的事情了,你io处理完了通知我一下。aio提供的事件处理接口CompletionHandler,定义了回调函数,这些函数再io完成后会被自动的调用。
参考文章:https://www.zhihu.com/question/40930889/answer/146567853
9.HashMap实现原理,如何保证HashMap的线程安全?
链表的数组。
Map<Object, Object> map = Collections.synchronizedMap(new HashMap<>());
10.JVM内存结构,为什么需要GC?
JVM内存结构分析.jpg方法区,堆,虚拟机栈,本地方法栈,程序计数器。
重点参考文章:JVM内存结构
垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存;
-
引用计数法: 思路简单,执行效率高。但是无法检测循环引用。
-
可达性分析算法:
-
标记清除算法
-
复制算法
-
标记整理算法
-
分代收集算法
- 根搜索算法,从GCRoot出发,不联通的图极为垃圾。作为GC Root的对象有:
a. 虚拟机栈中的引用对象(本地变量表)
b. 方法区中常量引用的对象
c. 方法区中静态属性引用的对象
d. 本地方法栈中引用的对象(Native对象)
重点参考文章:深入理解 Java 垃圾回收机制 , 一个面试官对面试问题的分析
11.NIO模型,select/epoll的区别,多路复用的原理
12.Java中一个字符占多少个字节,扩展再问int, long, double占多少字节
byte 1字节
short 2字节
int 4字节
long 8字节
float 4字节
double 8字节
char 2字节
boolean 1字节
13.创建一个类的实例都有哪些办法?
new
clone
newInstance
14.final/finally/finalize的区别?
final 限定符,不能被继承等
finally 配合try使用,一定会被执行
finalize Object中的方法,被CG之前执行,只执行一次。
15.Session/Cookie的区别?
一个在服务器上,一个存在客户端。
16.String/StringBuffer/StringBuilder的区别,扩展再问他们的实现?
String字符串常量
StringBuffer字符串变量(线程安全)
StringBuilder字符串变量(非线程安全)
17.Servlet的生命周期?
Web Client 向Servlet容器(Tomcat)发出Http请求
Servlet容器接收Web Client的请求
Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。
Servlet容器创建一个HttpResponse对象
Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet 对象。
HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
Servlet容器把HttpServlet的响应结果传给Web Client。
18.如何用Java分配一段连续的1G的内存空间?需要注意些什么?
使用数组即可分配连续1G内存,由于分配大内存容易出现 OutOfMemoryError: Java heap space,因此当需要使用这么大内存时首先考虑优化算法。
19.Java有自己的内存回收机制,但为什么还存在内存泄露的问题呢?
内存泄露 : 如果分配出去的内存得不到释放,及时回收,就会引起系统运行速度下降,甚至导致程序瘫痪,这就是内存泄露
stackoverflow上关于创建内存泄漏的讨论
资源不关闭就会导致内存泄漏,比如数据库连接,文件等
20.什么是java序列化,如何实现java序列化?(写一个实例)?
java中的序列化机制能够将一个实例对象(只序列化对象的属性值,而不会去序列化什么所谓的方法。)的状态信息写入到一个字节流中使其可以通过socket进行传输、或者持久化到存储数据库或文件系统中;然后在需要的时候通过字节流中的信息来重构一个相同的对象。
一般而言,要使得一个类可以序列化,只需简单实现java.io.Serializable接口即可。
21.String s = new String("abc");创建了几个 String Object?
2个。
目录列表
一、数据结构与算法基础
二、Java基础
三、JVM
四、多线程/并发
五、Linux使用与问题分析排查
六、框架使用
七、数据库相关
八、网络协议和网络编程
九、Redis等缓存系统/中间件/NoSQL/一致性Hash等
十、设计模式与重构
本文是针对知乎文章《成为Java顶尖程序员,先过了下面问题》的解答