Java常规技术题(上篇)

这篇博客详细探讨了Java编程的一些核心概念和技术,包括Java的'一次编写,处处运行'理念,JVM的工作原理,Java中不存在全局变量的原因,main方法的关键字解析,内存泄漏,以及==和equals的区别等。还深入讨论了Java中的流,字符串处理,异常处理,多线程和线程状态,以及对象创建和生命周期。此外,文章还涵盖了构造器、反射、抽象类与接口、异常处理的关键字如throws和throw的用法,以及线程的sleep()和wait()方法的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Java 的 “一次编写,处处运行”如何实现?

JAVA之所以能实现 一次编译,到处运行,是因为JAVA在每个系统平台上都有 JAVA虚拟机(JVM),JAVA编译的中间文件class是由JAVA虚拟机在运行时动态转换为对应平台的机器代码.

2. 描述JVM运行原理。

Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。这个平台的结构如下图所示:   运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。

3. 为什么Java没有全局变量?

Global variables(全局变量) 是指可以全局访问的变量, Java不支持全局变量,原因如下:

  1. 全局变量破坏了引用的透明性。
  2. 全局变量制造了命名空间冲突。
    可以使用properties类将想要全局有效的变量值写在properties文件中,那么在何处用时都从此properties文件中读取这个变量的值就可以了,此值在任何时候都可以修改的
    说明:我们平时在类中声明的只是相对类而言是全局变量,不是真正意义的全局变量

4. 说明一下public static void main(String args[])这段声明里每个关键字的作用。

Public 是一个访问权限(访问修饰符)公共
static 修饰的成员称为类成员或者静态成员
void 当方法定义时用void修饰时,表示没有返回值
String 类来创建和操作字符串

5. Java 是否存在内存泄漏?

java中内存泄露的发生场景,通俗地说,就是程序员可能创建了一个对象,以后一直不再使用这个对象,这个对象却一直被引用,即这个对象无用但是却无法被垃圾回收器回收的,这就是java中的内存泄露,一定要让程序将各种分支情况都完整执行到程序结束,然后看某个对象是否被使用过,如果没有,则才能判定这个对象属于内存泄露。

6. ==与equals的区别。

"= ="除了比较基本数据之外都是比较的内存地址"
equals"除了没有没有重写equals方法的类之外都是比较的内容

7. Java中有几种类型的流?

Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。

8. 如何用Java代码列出一个目录下所有的文件。

File file=new File(“H:\”);
for(File temp:file.listFiles()){
if(temp.isFile()){
System.out.println(temp.toString());
}
}

9. &和&&的区别。

1、&与&&都可以用作逻辑与的运算符,当两边的结果都为true时,运算结果才为true,否则只要有一方运算结果是false,运算结果就为false。
2、&&在开发过程中用到的概率比&大,因为&&具有短路的功能,只要第一个表达式是false,就不会再进行判断。例如:if(str!=null && !str.equals("")){}
当str==null时,后面的表达式就不会继续执行,但是
if(str!=null & !str.equals("")){}当str==null时,程序会报空指针异常,因为&不具有短路的功能。
3、&同时也是位运算符,就是我们通常所说的按位与运算,当&的左右两边都是Boolean型表达式时或Boolean值时,就执行按位与运算。

10. 构造器(constructor)是否可被重写(override),其规范是什么?

构造器(构造方法)Constructor不能被继承,因此不能重写Override,但可以被重载Overload(不同参数即可)。
每一个类必须有自己的构造函数,在创建对象时自动调用,如果添加有参构造函数后,默认无参构造函数则被覆盖。子类不会覆盖父类的构造函数,但是在创建子类对象的时候,会自动调用父类构造函数。 

11. JAVA 的反射机制的原理。

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

12. 静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?

内部类是类中类(内部类不为同一包的其他类可见,具有很好的封装性),分为静态内部类,成员内部类,局部内部类以及匿名内部类;局部内部类写在方法里面;用到最多的就是匿名内部类。 
1. 静态的内部类称为嵌套类,嵌套类不能直接引用外部类的non-static属性和方法,创建嵌套类对象时不依赖外部类对象;
2. 静态内部类没有了指向外部的引用,和C++的嵌套类很相像了,Java内部类和C++嵌套类最大的不同在于是否具有指向外部引用这点;
3. 在任何非静态内部类中,都不能有静态数据、静态方法或者又一个静态内部类(也就是不止一层),然后静态内部类可以拥有这一切。 

13. 如何将String类型转化成Number类型。

Integer类的valueOf方法可以将String转成Number

14. 什么是值传递和引用传递?

对象被值传递,意味着传递了对象的一个副本。因此,就算是改变了对象副本,也不会影响源对象的值。
对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。

15. Java的访问修饰符是什么?

在Java编程语言中有四种权限访问控制符,这四种访问权限的控制符能够控制类中成员的可见性。 
public是公共的,被public所修饰的成员可以在任何类中都能被访问到。
protected是受保护的,受到该类所在的包所保护。 
friendly是友好的,即在成员的前面不写任何的访问修饰符的时候,默认就是友好的。所谓友好的,是对同一package的类友好。  
private是私有的,即只能在当前类中被访问到,它的作用域最小。

16. Java 基础数据类型有哪些?

byte(字节)   short(短整型)  int(整型)  long(长整型)  float(浮点型)  double(双精度)	    char(字符型)  boolean(布尔型)  

17. hashCode()和equals()方法的重要性体现在什么地方?

Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法的实现对HashMap的精确性和正确性是至关重要的。

18. switch 中用于判断的表达式,可以用哪些数据类型?

  1. int
    2.char
    3.byte
    4.short
    5.枚举

19. char型变量中能不能存贮一个中文汉字?为什么?

 Java里采用了Unicode编码格式,Unicode编码中一个char型占用2个字节,而一个汉字也是占用2个字节,所以可以存储中文汉字。
 备注:C语言里,char占用1个字节,不用存汉字。

20. 静态变量和实例变量的区别?

在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

21. 是否可以从一个static方法内部发出对非static方法的调用?

不可以。因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。也就是说,当一个static方法被调用时,可能还没有创建任何实例对象,如果从一个static方法中发出对非static方法的调用,那个非static方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,一个static方法内部发出对非static方法的调用。

22. Integer与int的区别?

1、int是基本数据类型,Integer是包装类;
2、int的默认值是0,Interger的默认值是null;

23. Overload和Override的区别。参数列表相同,返回值不同的方法,是否是重载方法?

Overload是重载的意思,Override是覆盖的意思,也就是重写。
重载是指在一个类里,方法名相同,参数不同;
重写是指子类继承父类,子类里重新编写了父类中的同名(同参数)方法,也就是覆盖了父类的方法; 不是!因为重载必须要求参数列表不同!

24. 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)?

接口可以继承多个接口。抽象类可以实现(implements)接口,抽象类是可继承具体类。
备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答。
只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。

25. 面向对象有哪三大特性?

1、面向对象有三大特性,分别是:封装、继承和多态。
2、封装:面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个类中,有些属性是不希望公开的,或者说被其他对象访问的,所以我们使用private修饰该属性,使其隐藏起来;类中提供了方法(用public修饰),常用的是get、set方法,可以操作这些被隐藏的属性,其他类可以通过调用这些方法,改变隐藏属性的值!
封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装的最基本单位,面向对象的封装比传统语言的封装更为清晰、更为有力。
3、继承:在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,使用extends关键字实现继承;子类中可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。
4、多态:多态就是在声明时使用父类,在实现或调用时使用具体的子类;即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性,多态增强了软件的灵活性和扩展性。这里可以举个例子,比如声明时使用的是动物类,调用时传递的是一个猫类(动物类的子类)的对象,具体执行父类里动物——吃的方法时,实际执行的是猫——吃的方法。

26. abstract class和interface有什么区别?

1、抽象类里面可以用普通方法,而接口中的方法全部都是抽象的;
2、在应用范围上来说,接口往往在程序设计的时候,用来定义程序模块的功能,方便各模块协同工作;抽象类是对相似类进行抽象,形成一个抽象的父类可供重用!

27. 如何理解Java中的Serialization和Deserialization。

串行化(serialization)是指将一个对象的当前状态转换成字节流(a stream of bytes)的过程,而反串行化(deserialization)则指串行化过程的逆过程,将字节流转换成一个对象,打回原形。

28. String是最基本的数据类型吗?

1、String是个类,不是基本数据类型;
2、基本数据类型包括byte、int、char、long、float、double、boolean和short。

29. 如何实现字符串的反转及替换。

1.通过jdk自带reverse的方法
public class InvertString {
public static void main(String[] args) {
String a=“abcde”;
StringBuilder b = new StringBuilder(a);
System.out.print(b.reverse().toString());
}
}
注:String类本身没有反转类,需要包装成Stringbuiler或者是StringBuffer类。
2.通过自己写循环。
利用String.toCharArray()方法,将String转成一个char型数组,然后用数组遍历的方式从后向前遍历。
public String reverse(String s){
char ch[] = s.toCharArray();
int start = 0, end = ch.length-1;
char temp;
while(start<end){
temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start++;
end–;
}
String s1 = String.copyValueOf(ch);
return s1;
}

或者是这样
public static String reverse2(String s) {
int length = s.length();
String reverse = “”;
for (int i = 0; i < length; i++)
reverse = s.charAt(i) + reverse;
return reverse;
}

30. String s = new String(“xyz”);创建了几个字符串对象。

两个对象,要理解这个,就要知道string类的工作原理。
public class StringTest {
public static void main(String[] args){
String s1=“Hello”;
String s2=“Hello”;
String s3=new String(“Hello”);
System.out.println(“s1和s2 引用地址是否相同:”+(s1 == s2));
System.out.println(“s1和s2 值是否相同:”+s1.equals(s2));
System.out.println(“s1和s3 引用地址是否相同:”+(s1 == s3));
System.out.println(“s1和s3 值是否相同:”+s1.equals(s3));
}
}
输出结果:
s1和s2 引用地址是否相同:trues
s1和s2 值是否相同:trues
s1和s3 引用地址是否相同:falses
s1和s3 值是否相同:true

31. String 和StringBuffer的区别。

1、String是个不可变长度的字符串,而StringBuffer是个可变长度的字符串;
2、在对String类进行操作的时候(例如增加字符),实际上是在内存中产生了一个新的String对象; 而StringBuffer是给原对象增加字符,不是新创建一个对象;

32. 数组有没有length()这个方法?

String有没有length()这个方法? 数组没有length()这个方法,有length的属性。String有length()这个方法。

33. final, finally, finalize的区别。

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用

34. Errror , Exception,RuntimeException区别

Error(错误)表示系统级的错误和程序不必处理的异常,是java运行环境中的内部错误或者硬件问题。比如:内存资源不足等。对于这种错误,程序基本无能为力,除了退出运行外别无选择,它是由Java虚拟机抛出的。 
Exception(违例)表示需要捕捉或者需要程序进行处理的异常,它处理的是因为程序设计的瑕疵而引起的问题或者在外的输入等引起的一般性问题,是程序必须处理的。
Exception又分为运行时异常,受检查异常。
运行时异常,表示无法让程序恢复的异常,导致的原因通常是因为执行了错误的操作,建议终止程序,因此,编译器不检查这些异常。
受检查异常,是表示程序可以处理的异常,也即表示程序可以修复(由程序自己接受异常并且做出处理), 所以称之为受检查异常。 
Exception体系包括RuntimeException体系和其他非RuntimeException的体系:
① RuntimeException:RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
 ②其他非RuntimeException(IOException等等):这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。 

35. Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用。

throws是获取异常
throw是抛出异常
try是将会发生异常的语句括起来,从而进行异常的处理,
catch是如果有异常就会执行他里面的语句,
而finally不论是否有异常都会进行执行的语句。

36. throw和throws有什么区别?

throws是用来声明一个方法可能抛出的所有异常信息,而throw则是指抛出的一个具体的异常类型。

37. 请说一下你常用的几种异常?

空指针异常; NullPointerException
数组下标越界; ArrayIndexOutOfBoundsException
类型转换异常; ClassCastException
算数异常,例如除数为零;ArithMeticException
IO异常,比如说找不到文件; FileNotFoundException
找不到类异常; ClassNotFoundException
sql异常,例如sql语句不能正常运行;…

38. 线程的基本概念?线程的基本状态以及状态之间的关系

1、是程序执行流的最小单元。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
2、开始时:就绪状态,等待cpu调用后进入运行状态,运行过程中遇到阻塞事件,进入阻塞状态,等待阻塞事件结束后,重新进入就绪状态;如果没有阻塞事件,运行结束后,则进入结束状态。

39. sleep() 和 wait() 有什么区别?

  sleep就是暂停当前线程一段时间,把cpu让给其他线程使用,到时后会自动恢复。调用sleep不会释放对象锁。 wait方法导致本线程放弃对象锁,进入等待,只有等到本对象的notify方法(或notifyAll)后本线程才进入就绪状态,等待执行。 

40. 多线程有几种实现方法?

多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值