1、如果将程序的main()方法定义成如下格式,运行程序时会怎样?
void main(String[] args){
……
}
错误: 在类XXX中找不到 main 方法, 请将 main 方法定义为:public static void main(String[] args)
2、关于Java程序的main()方法,回答下面问题。
(1) 说明main()方法声明中各部分的含义。
main()方法是Java程序的入口点,它是在程序启动时被执行的。它必须声明为public,表示它可以在任何地方访问。静态意味着它是一个静态成员函数,属于类而不是对象。void表示它没有返回值。因此,public static void main(String[] args)的含义是:一个静态的、公共的、不返回任何值的函数,接受一个字符串数组作为参数。
(2) public static void main(String[] args)写成
static public void main(String[] args)会怎样?
合法但不符合习惯
(3) public static void main(String[] args)写成
public void main(String args)会怎样?
错误: 在类 XXX 中找不到 main 方法, 请将 main 方法定义为:
public static void main(String[] args)
需要接受一个字符串数组作为参数。这个参数用于从命令行接收输入,因此它必须是一个字符串数组。
3、试说明下面三条语句的作用:
System.out.println("Hello World!");
System.out.print("Hello World!");
System.out.println();
2.5 Java源文件命名规则:
源文件的拓展名必须是.java,如果源文件有多个类,则虽多只能有一个public类,如果有的话,那么源文件的名字必须与这个public类的名字相同,如果没有public类,那么源文件的名任意命名
2.6 java的主类是什么样的类
在Java中,主类(也称为入口类)是一个包含main()方法的类。
1、2*8最有效率的运算方法是怎样的?
2左移3位,8左移1位
2、判断一个整数n是奇数还是偶数,如何用位运算来实现?
判断一个整数n是奇数还是偶数,可以使用位运算来实现。具体方法是使用n的二进制表示中的最低位(即二进制位0或1)来判定。如果最低位为0,则n是偶数;如果最低位为1,则n是奇数。
3、如何在不采用临时变量的情况下实现两个数的交换?
a = a ^ b a = a + b
b = a ^ b b = a - b
a = a ^ b a = a – b
4、下面两个import语句有何不同?
import java.util.Scanner;
import java.util.*;
这个语句只导入了java.util包中的Scanner类
这个语句导入了java.util包中的所有类。
1、String 属于基础的数据类型吗?
String 不属于基础类型,属于引用数据类型;基础类型有 8 种:byte、short、int、long、float、double、boolean、char。
2、Java 中操作字符串的都有哪些类?它们之间有什么区别?
String:不可变字符串,创建后不能修改,适用于字符串不需要频繁修改的情况,内存占用较小。
StringBuilder:可变字符串,可以随时修改,适用于字符串需要频繁修改的情况,内存占用较大。
StringBuffer:可变字符串,可以随时修改,适用于字符串需要频繁修改的情况,内存占用较大,与StringBuilder类似,但线程安全。
3、String s="Hello";
与String s=new String("Hello");有何不同?
String str1 = "hello";
String str2 = "hello"; 与
String str1 = new String("hello");
String str2 = new String("hello"); 有何不同?
String str1 = “hello”; 引用str1被存放在栈区中,字符串常量“hello”被存放在常量池中,引用str1指向了常量池中的“hello”(str1存放着它的首地址)
String str2 = new String(“hello”);引用str2被存放在栈区,同时在堆区开辟一块内存存放新的String类型对象
常量池的字符串常量,不能重复出现。当定义常量时,编译器先去常量池查找该常量是否已存在,如果不存在,则在常量池创建一个新的字符串常量;如果已经存在,则不再创建,而是把新的String类型引用指向已存在的字符串常量,也就是说,在常量池不会开辟新的内存。在堆中创建新的内存空间时,不考虑该String类对象的值是否已经存在。也就是说:不管字符串的值是否重复,每一次new都会在堆区开辟一块新的内存,用来存放新定义的String类对象。
4、以下正则表达式的含义分别是什么?
(1)^[1][358]\d{9}$
手机号码验证:匹配一个以1开头、第2个数字只能是3或5或8、后面有9个0-9之间的数字的字符串。
(2)^[1-9][0-9]{4,14}$
验证号码合法性(5~15位、全是数字、不以0开头)
(3)^[a-zA-Z]{1}([a-zA-Z0-9]|[\._]){4,19}$
校验用户账号合法性(只能输入5-20个以字母开头、可带数字、“_”、“.”的字符串)
1、在静态方法showAve()方法体内,能否调用show()方法?为什么?反过来,在show()方法体内调用showAve(),可以吗?
在static方法体内,不能直接调用非静态方法,只能通过对象间接调用。
反过来,非静态方法内,可以直接调用静态方法。
2、main方法为什么必须是static的?
因为main方法是程序的入口,最先被调用,是由Java虚拟机在类外调用的。
此时对象尚未产生,故Java虚拟机只能通过类名来调用main方法,所以main方法必须是static的。
3、以下程序中static去掉会怎么样?
public class Ex1{
static int m=2;
public static void main(String args[ ]) {
Ex1 obj1=new Ex1( );
Ex1 obj2=new Ex1( );
obj1.m=m+1;
System.out.println("m="+obj2.m);
}
}
若去掉static,则此处会有编译错误。因为不知道这个m是哪个对象的m。
main方法是static方法,不需要通过对象来调用,也就没有当前对象了。
4、以下程序求10~100之间的所有素数。如果将prime方法设计为非静态方法,则如何在main方法中调用?
public class findPrime {
public static boolean prime(int n){
for (int k=2;k<=Math.sqrt(n);k++) {
if ( n % k==0)
return false;
}
return true;
}
public static void main(String args[]) {
for (int m=10;m<=100;m++) {
if ( prime(m) )
System.out.print(m+" , ");
}
}
}
public static void main(String args[]) {
findPrime x=new findPrime();
for (int m=10;m<=100;m++) {
if ( x.prime(m) )System.out.print(m+" , "); }}
5、以下代码有无错误?为什么?
public class Test{
long a[ ] = new long[10];
public static void main ( String arg[ ] ) {
System.out.println ( a[6] );
}
}
此处会有编译错误。因为数组a是非静态成员变量,而main方法是static方法,在静态方法中使用非静态成员,必须通过对象来使用,否则就不知道这个a[6]是哪个对象的a[6]。
6、匿名对象在使用过一次后还能否再使用?为什么?
new Cylinder().SetCylinder(2.5, 5,3.14);
不能再使用。因为该对象没有引用变量。
所以在使用一次后,会被自动垃圾回收机制 回收该对象的空间。
因此,匿名对象适合于只使用一次的场合
1、== 和 equals 的区别是什么?
== 对于基本类型来说是值比较,对于引用类型来说比较的是引用(即首地址);
equals 默认情况下是引用比较,但是很多类重写了 equals 方法,比如 String类重写了equals 方法,把它变成了字符串的值比较。所以对于String类型, equals 比较的是字符串内容是否相等。
2、final 在 Java 中有什么作用?
final 修饰的类叫最终类,该类不能被继承。
final 修饰的方法不能被重写。
final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
思考:String类中的方法是否都是final的?
答:是。因为final类不能被继承,也即无子类,所以其方法都不可能被重写。因此,所有方法自动、隐式地加了final
3、抽象类必须要有抽象方法吗?
抽象类不一定要包含抽象方法。抽象类是一个抽象的概念,它定义了一组通用的属性和方法,用于被它的子类实现或者覆盖。抽象类可以包含抽象方法,也可以包含具体方法。如果一个抽象类包含抽象方法,那么它的子类必须实现这些抽象方法,否则子类也必须声明为抽象类
4、普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能直接实例化对象,普通类可以直接实例化对象。
5、抽象类能使用 final 修饰吗?
不能,定义抽象类就是为了让其他类继承的。如果加了final, 该类就不能被继承,这样彼此就会产生矛盾。
6、多态性有哪两种?有何异同?
多态性有两种:一种是方法覆盖技术,通过在子类中覆盖父类的同名方法(方法头完全相同)来实现,在运行时根据调用这个方法的对象来确定哪个方法被调用。也叫运行时多态性。
另一种是方法重载技术。方法名相同,但参数类型或个数不同。编译时根据实参的类型、个数来判断调用的是哪个方法。也叫编译时多态性。
同:方法名相同
异:方法重载发生在同一个类中,方法头不能完全相同。方法的参数必须有不同。方法覆盖发生在父类和子类之间,或接口和实现类之间。方法头必须完全相同。
7、接口和抽象类有什么区别?
实现: 抽象类的子类使用 extends 来继承;接口必须用 implements 来实现接口
构造函数: 抽象类可以有构造函数;接口不能有。
实现数量: 类可以实现很多个接口;但是只能继承一个抽象类。
访问修饰符: 接口中的方法默认使用 public 修饰;
抽象类中的方法可以是任意访问修饰符。
1、try-catch-finally 中哪个部分可以省略?
对所有的异常,finally都可以省略
仅仅对RuntimeException 及其子类,catch块可以省略,因为系统会自动处理。
catch 和 finally不能同时省略。有 try 的时候,后面必须跟 至少一个 catch 或者 finally。
2、try-catch-finally 中,如果 catch块 中 return 了,finally 还会执行吗?
finally 一定会执行,即使是 catch 中 return 了,catch 中的 return 会等 finally 中的代码执行完之后,才会执行。
3、final、finally、finalize 有什么区别?
final:是修饰符,可以修饰类、方法和变量。详见第八章思考题“final 在 Java 中有什么作用?”
finally:用于异常处理。是 try{} catch{} finally{} 最后一部分,表示不论发生任何情况都会执行。finally 部分可以省略,但如果 finally 部分存在,则一定会执行 finally 里面的代码。
finalize:是 Object 类的一个方法。当垃圾回收器将要释放无用对象的内存时,会先自动调用该对象的finalize()方法。
4、throw 和 throws 有何区别?
throws:是声明可能会抛出一个异常。throws子句放在方法声明的最后
throw:是真实抛出一个异常。通常 满足某个if条件时,会throw一个异常对象。
- Collection 和 Collections 有什么区别?
Collection是集合层次的根接口,所有集合都是它的子接口的实现类,比如:List和Set接口的实现类
java.util .Collections类是工具类,该类中的所有方法都是static的。常用方法有:Collections.sort(list)等
- List、Set、Map 之间的区别是什么?
List元素有序,允许元素重复
Set包含AbstractSet,HashSet,TreeSet;AbstractSet,HashSet元素无序,TreeSet元素有序(二叉树排序);都不允许元素重复
Map包含AbstractMap,HashMap,TreeMap ;AbstractMap,HashMap元素无序,TreeMap元素有序(二叉树排序);key值唯一,value可以重复
- 如何决定使用 HashMap 还是 TreeMap?
HashMap的速度通常都比TreeMap快,如:插入、删除、查找元素这类操作。因此,通常选用HashMap,只有在需要排序功能的时候,才使用TreeMap。
- 说一下 HashMap 的实现原理?
HashMap 基于 Hash 算法(即散列方法)来实现的,通过 put(key,value)存储,get(key)来获取。当传入键(key)时,HashMap 会根据 key. hashCode() 计算出 hash 值,即存储位置,将值(value)保存到该存储位置里。
- ArrayList 和 LinkedList 的区别是什么?
存储结构不同:ArrayList 是顺序存储的线性表,采用动态数组实现。而 LinkedList 是链接存储,采用双向链表。
随机访问元素效率:ArrayList 比 LinkedList 在随机访问的时候效率要高。
插入和删除元素效率:在非表尾的插入和删除操作,LinkedList 要比 ArrayList 效率要高。
综合来说,如果需要频繁读取表中元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList。
- 如何实现数组和 List 之间的转换?
数组转 List:使用 Arrays. asList(array) 进行转换。其中,Arrays为数组工具类。
List 转数组:使用 List 自带的 toArray() 方法。
7. 迭代器 Iterator 是什么?如何使用?
Iterator 是一个接口,用途:提供了一种通用方法遍历任何 Collection。
迭代器的使用步骤:
- 调用集合对象的iterator()方法获取Iterator对象,即迭代器的实现类对象,使用Iterator接口接收(多态)
- 使用Iterator接口中的hasNext()方法判断还有没有下一个元素。
- 使用Iterator接口中的next()方法取出集合中的下一个元素。
- 做一个网站的后台服务程序,当有一个客户连接请求到来时,应该开辟一个进程还是开辟一个线程去为他服务?为什么?
应开辟一个线程。因为多个线程共同拥有一个地址空间,所以切换效率高。而多进程时,每个进程拥有一块地址空间,切换效率低。
对于多客户系统,每个客户应开辟一个线程去为他服务。这对于服务器端合理利用资源,效率提升都有好处。
- 多线程能实现多个线程的真正并行吗?为什么?
如果系统只有一个CPU,则无法实现真正的并行。系统只能把CPU的时间分成多个时间片,分配给各线程。多个线程之间不断切换,由于切换速度很快,所以给我们多个线程同时运行的错觉。这种方式称为“并发”。
如果系统有多个CPU,就可以实现真正的并行。
- 进程和线程有何区别?
进程是正在运行着的程序,进程是动态的。同一个程序可以运行多个,一个进程拥有一块地址空间。进程是系统运行程序的基本单位。
线程是一个比进程更小的执行单位。一个进程在其执行过程中可以产生多个线程,形成多条执行线路。
区别:
进程拥有独立的内存空间,而线程共享进程的内存空间。
进程的创建和销毁需要较大的系统开销,而线程的创建和销毁相对较小。
进程之间的通信需要使用进程间通信(IPC),而线程之间的通信可以通过共享内存来实现。
- 线程有哪几种状态?
五个状态,新建状态,就绪状态,运行状态,阻塞状态,消亡状态
5. 线程的 run() 和 start() 有何区别?
run() 方法是线程类中的普通方法,它只是定义了线程的执行逻辑,并不会立即执行。
start() 方法是线程类中的特殊方法,它负责启动线程的执行,并在启动时调用 run() 方法。
start() 方法会返回一个 Thread 对象,可以用来获取线程的状态、ID 等信息。