Java面试笔记(Java基础)

Java基础:

面向对象和面向过程的区别

面向过程是一件事“该怎么做”,面向对象是一件事“该谁来做”。然后那个谁就是对象,他要怎么做是他的事,反正最后一群对象合力把事情做好就行了。

Java的四个基本特性(抽象、封装、继承,多态)

Overload和Override的区别

构造器Constructor是否可被override

构造器不能被继承,也不能被重写。但是可以被重载。

访问控制符public,protected,private,以及默认的区别

是否可以继承String类

String和StringBuffer、StringBuilder的区别

hashCode和equals方法的关系

equals()方法是用来判断其他的对象是否和该对象相等.在object类中是对两个对象的地址值进行的比较。但是很多类都重写了equals方法,进行的是内容的比较。
hashCode()方法给对象返回一个hash code值。
1. 如果对象没有被修改的话,该对象多次调用hashCode()方法,该方法必须始终返回同一值。
2. 如果两个对象根据equals方法相等的,那么调用二者各自的hashCode()方法必须产生同一个int结果。
3. 并不要求根据equals方法不相同的对象,调用二者各自的hashCode()方法必须产生不同的integer结果。

需要注意的是当equals()方法被override时,hashCode()也要被override。按照一般hashCode()方法的实现来说,相等的对象,它们的hash code一定相等。

总的来说,Java中的集合有两类,一类是List,一类是Set。前者集合内的元素是有序的,可以重复,后者元素无序,不能重复。

对set来说,如果每次都用equals()方法,效率太低。

抽象类和接口的区别

  1. abstract class在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
  2. 抽象类可以有构造方法,接口中不能有构造方法。
  3. 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
  4. 从编程思想上来说,抽象类体现了一种继承的关系,要继承关系合理,父类和子类在概念上本质应该是相同的。比如鸽子继承鸟,鸟里面有一个方法是飞。但是如果你只是想有一个方法叫飞的话,可以写一个飞的接口,因为蝙蝠也可以有飞的方法。

自动装箱与拆箱

数据类型可以分为两大类:基本类型和引用类型。基本类型不是对象,不能调用对象的toString(),hashCode(),getClass(),equals()等方法。所以java提供了针对每种基本类型的包装类型。

自动装箱:把基本类型用它们对应的引用类型包装起来,使它们具有对象的特质

拆箱:跟自动装箱的方向相反,将引用类型重新简化为基本类型的数据。

自动装箱和拆箱是由编译器来完成的。

什么是泛型、为什么要使用以及泛型擦除

泛型程序设计意味着编写的代码可以被不同中类型的对象重用。增强代码的复用性。

在java中,无论何时定义了一个泛型,它都会自动生成一个相应的原始类型。我们叫这个过程为类型擦除。
Java中的泛型基本上都是在编译器这个层次上来实现的。在生成的字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器编译的时候去掉。这个过程就叫做类型擦除。

Java中的集合类及关系图

HashMap实现原理(看源代码)

HashTable实现原理(看源代码)

HashMap和HashTable区别

HashTable如何实现线程安全(看源代码)

ArrayList和vector区别(看源代码)

ArrayList和LinkedList区别及使用场景

Collection和Collections的区别

Concurrenthashmap实现原理(看源代码)

Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrenthashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。

concurrentHashMap内部使用段来表示这些不同的部分,每个段就是一个小的hashtable,他们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。

有些方法需要跨段,比如size()和containsValue(),他们需要锁定整个表而不是仅仅某个段,需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段。

Error、Exception区别

Error类指的是与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。这类错误导致的应用程序中断,仅靠程序本身无法恢复和预防。

Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意中止异常。

Exception又分runtime Exception和checked Exception,前者编译能通过,但是运行就中止了。后者编译不会通过,除非用try catch捕获。

Unchecked Exception和Checked Exception,各列举几个

runtime Exception:NullPointerException,IndexOutOfBoundsException

checked Exception:ClassNotFoundException,IOException,SQLException

Java中如何实现代理机制(JDK、CGLIB)

多线程的实现方式

  1. 创建Thread类,重写run函数
  2. 实现Runnable接口
  3. 实现Callable接口,重写call函数
Runnable和Callable区别
  1. callable规定的方法是call(),而Runnable规定的方法是run()
  2. callable任务执行以后可返回值,但是run不返回值
  3. call方法可以抛出异常,但是run不抛出异常
  4. 运行callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可了解任务执行情况,可取消任务的执行,还可以获取任务执行的结果。

线程的状态转换

如何停止一个线程

  1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
  2. 使用stop方法强行终止线程。
  3. 使用interrupt方法中断线程。

什么是线程安全

如果你的代码所在的进程有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

如何保证线程安全

Synchronized如何使用

用来修饰一个方法或者一个代码块的时候,能够保证同一时刻最多只有一个线程执行该段代码。
1. 当两个并发线程访问同一个对象object中的sychronized(this)同步代码块时,一个时间内只能有一个线程得到执行,另一个线程必须等到当前线程执行完这个代码块以后才能执行该代码。
2. 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其他synchronized(this)同步代码的访问将被阻塞,但是对于非synchronized(this)同步代码块仍然可以访问。
3. 当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。

synchronized关键字有两种用法:synchronized方法和synchronized块。
- synchronized方法:
缺陷:影响效率。
- synchronized块:
synchronized块是这样一个代码块,其中的代码必须获得对象synObject()的锁方能执行。

synchronized和Lock的区别

  1. Lock不是Java语言内置的,synchronized是java语言的关键字,因此是内置特性。Lock是一个类(接口),通过这个类可以实现同步访问。
  2. Lock和synchrinized不需要用户去手动释放锁,当synchronized方法执行完之后,系统会自动让线程释放对锁的占用,而Lock必须要用户手动释放锁。如果没有释放,有可能会导致死锁。
  3. Lock可以让等待锁的线程相应中断。
  4. Lock可以知道有没有成功获取锁。
  5. Lock可以提高多个线程进行读操作的效率。

多线程如何进行信息交互

notify():唤醒在此对象监视器上等待的单个线程
notifyAll():唤醒在此对象监视器上等待的所有线程。
wait():导致当前线程等待,直到其他线程调用此对象的notify或者notifyAll方法。

sleep和wait的区别(考察的方向是是否会释放锁)

wait()和sleep()最大的不同在于wait()会释放对象锁,而sleep()不会!

wait()和notify()必须在synchronized代码块中调用。

多线程与死锁

死锁是两个或更多线程阻塞着等待其他处于死锁状态的线程所持有的锁。死锁通常发生在多个线程同时但以不同的顺序请求同一组锁的时候。

例如,线程1锁住了A,然后尝试对B进行加锁,同时线程2已经锁住了B,接着尝试对A进行加锁,这时死锁就发生了。线程1永远得不到B,线程2也永远得不到A,并且他们永远也不知道发生了这样的事情。

如何才能产生死锁

什么叫守护线程,用什么方法实现守护线程

Java中有两类线程:用户线程和守护线程。用一个比较通俗的说话,任何一个守护线程都是整个JVM所有非守护线程的保姆。
只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作。只有当最后一个非守护线程停止工作,守护线程随着JVM一同结束工作。

Java线程池技术及原理

java并发包concurrent及常用的类

volatile关键字

Java中的NIO,BIO,AIO分别是什么

IO和NIO区别

序列化与反序列化

常见的序列化协议有哪些

内存溢出和内存泄漏的区别

Java内存模型及各个区域的OOM,如何重现OOM

出现OOM如何解决

用什么工具可以查出内存泄漏

Java内存管理及回收算法

Java类加载器及如何加载类(双亲委派)

xml解析方式

Statement和PreparedStatement之间的区别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值