自己总结的java面试题,持续更新中ing

  1. java语言的特点是什么?
    1.面向对象性:两个基本概念:类、对象;三大特性:封装、继承、多态
    2.健壮性:吸收了C/C++语言的优点,但去掉了其影响程序健壮性的部分(如指针、内存的申请与释放等),提供了一个相对安全的内存管理和访问机制
    3.跨平台性:通过Java语言编写的应用程序在不同的系统平台上都可以运行。“Write once , Run Anywhere”

  2. 为什么要设置path(或者说,设置path的目的是什么)?
    目的是为了在控制台的任何文件路径下,都可以调用jdk指定目录下的所有指令。

  3. JDK,JRE和JVM的关系是什么?
    在这里插入图片描述
    JDK = JRE + 开发工具集(例如Javac编译工具等)
    • JRE = JVM + Java SE标准类库

  4. GC是什么? 为什么要有GC?
    GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。

  5. 成员变量(属性)和局部变量的区别?

  6. 数组元素的属性和对象属性的默认初始化赋值
    在这里插入图片描述

  7. 方法的重载(overload)
    在这里插入图片描述

  8. Java权限修饰符public、protected、(缺省)、private置于类的成员定义前,
    用来限定对象对该类成员的访问权限。
    在这里插入图片描述

  9. 方法的重写(override/overwrite)
    在这里插入图片描述

  10. this和super的区别
    在这里插入图片描述

  11. 对象的多态性:父类的引用指向子类的对象
    在这里插入图片描述

  12. 包装类(Wrapper)的使用
    在这里插入图片描述
    在这里插入图片描述

  13. 谈谈final, finally, finalize的区别
    final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载

finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)

finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的
  1. 接口和抽象类之间的对比
    在这里插入图片描述
    Java 8中关于接口的改进
    Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完
    全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行
其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中
找到像Collection/Collections或者Path/Paths这样成对的接口和类。

默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。
我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认
方法。
  1. Throw和Throws的区别
    Throw:
作用在方法内,表示抛出具体异常,由方法体内的语句处理。
具体向外抛出的动作,所以它抛出的是一个异常实体类。若执行了Throw一定是抛出了某种异常。

Throws:

作用在方法的声明上,表示如果抛出异常,则由该方法的调用者来进行异常处理。
主要的声明这个方法会抛出会抛出某种类型的异常,让它的使用者知道捕获异常的类型。出现异常是一种可能性,但不一定会发生异常。 
  1. java中创建线程的方法有几种,都有哪些?怎么创建?
    更加详细内容,点击链接
有四种方法,
1)继承Thread类创建线程

2)实现Runnable接口创建线程

3)使用Callable和Future创建线程

4)使用线程池
  1. thread中常用的方法有哪些?举例说明?
    常见方法如下
1.start():启动当前线程;调用当前线程的run()
	2.run(): 通常 需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
	3.currenThread();静态方法,返回执行当前代码的线程
	4.getName(),获取当前线程的名字
	5.setName(),设置当前线程的名字
	6.yield():释放当前cpu的执行权
	7.join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才会结束阻塞状态
	8.stop(),,已过时。当执行此方法时,强制结束当前进程
	9. sleep(long millitime) :让当前线程"睡眠"指定的millitime毫秒。在指定的millitime毫秒时间内,当前线程是阻塞状态
	10.isAlive():判断当前线程是否存货
  1. sleep()和wait()的区别?
相同点:
		一旦执行方法,都可以使得当前的线程进入阻塞状态。
不同点:
		1.两个方法的声明位置不同,Thread类中声明sleep(),Object类中声明wait()
		2.调用的要求不同,sleep()可以在任何需要的场景下调用,wait()必须使用在同步代码块和同步方法中使用。
		3.关于是否释放同步监视器,如果两个方法都使用在同步代码块或者同步方法中,sleep()不会释放锁,wait()会释放锁。
对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

在调用sleep()方法的过程中,线程不会释放对象锁。

而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备

从使用角度看,sleep是Thread线程类的方法,而wait是Object顶级类的方法。

sleep可以在任何地方使用,而wait只能在同步方法或者同步块中使用。

CPU及资源锁释放

sleep,wait调用后都会暂停当前线程并让出cpu的执行时间,但不同的是sleep不会释放当前持有的对象的锁资源,到时间后会继续执行,而wait会放弃所有锁并需要notify/notifyAll后重新获取到对象锁资源后才能继续执行。

sleep和wait的区别:
1、sleep是Thread的静态方法,wait是Object的方法,任何对象实例都能调用。
2、sleep不会释放锁,它也不需要占用锁。wait会释放锁,但调用它的前提是当前线程占有锁(即代码要在synchronized中)。
3、它们都可以被interrupted方法中断。
  1. String常用方法
 int length():返回字符串的长度: return value.length
 char charAt(int index): 返回某索引处的字符return value[index]
 boolean isEmpty():判断是否是空字符串:return value.length == 0
 String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
 String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
 String trim():返回字符串的副本,忽略前导空白和尾部空白
 boolean equals(Object obj):比较字符串的内容是否相同
 boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大
小写
 String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
 int compareTo(String anotherString):比较两个字符串的大小
 String substring(int beginIndex):返回一个新的字符串,它是此字符串的从
beginIndex开始截取到最后的一个子字符串。
 String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字
符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
 boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
 boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
 boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的
子字符串是否以指定前缀开始
 boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列
时,返回 true
 int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
 int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出
现处的索引,从指定的索引开始
 int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
 int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后
一次出现处的索引,从指定的索引开始反向搜索
注:indexOf和lastIndexOf方法如果未找到都是返回-1
  1. String与基本数据类型转换
    在这里插入图片描述
  2. StringBuffer类的常用方法
StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转
  1. 面试题:对比String、StringBuffer、StringBuilder
String(JDK1.0):不可变字符序列
StringBuffer(JDK1.0):可变字符序列、效率低、线程安全
StringBuilder(JDK 5.0):可变字符序列、效率高、线程不安全
注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值。
  1. ArrayList,LinkedList,Vector三者之间的异同?
    源码分析:https://blog.csdn.net/qq_2662385590/article/details/110129298
    相同点:
三个类都是实现了List接口,存储数据的特点相同,存储有序的,可重复的数据。

不同点:

ArrayList:
				作为List接口的主要实现类;
				线程不安全的,效率高;
				底层使用Object[] 存储。
	LinkedList:
				对于频繁的插入,删除操作,使用此类效率比ArrayList高;
				底层使用双向链表存储。
	Vector:
			作为List接口的古老实现类;
			线程安全的,效率低;
			底层使用Object[] 存储。
  1. java 的反射机制和面向对象的封装性 是不是矛盾的?怎么理解两个技术?
两种技术乍一看上去有点矛盾的

封装性告诉我们私有的 别的地方不能用,而反射呢告诉我们可以用私有的 这样看不就白封装了吗 

两者之间不矛盾

对于封装性我们 设计一个类的时候 属性 方法 构造器等等 该私有的时候私有(private) 该 公共的时候公共(public)

封装性给我们的启示是:当我们看到一个类写了一些私有的方法,一些公共的方法时 就告诉我们私有的方法就不要用了

就用公共的方法就可以了 因为私有的方法可能类内部用了 这里体现了封装性。比如单例模式  你要想造对象 就不要用

私有的构造器了 我已经把对象造好了直接用就行

反射 告诉我们可以调 但是不建议调私有的方法,因为可能公共的方法更好 加了一些逻辑 。

封装性解决的问题是 建议 调那个的问题 公共的调就可以了 私有的不要掉了就 私有的属性不建议你直接修改 建议你通过get set方法修改。

反射解决的是能不能调的问题

所以两者不矛盾。

猜你喜欢

转载自blog.csdn.net/qq_2662385590/article/details/109896863