一、简答题
说明一下 Java语言与平台无关的实现原理。
答:
(1)Java源代码编译后会生成平台无关的字节码文件;
(2)字节码文件可以在Java虚拟机上运行,不同平台虚拟机不同。可以把字节码在特定平台上解释执行。
说明String类和StringBuilder类的区别。
答:
(1)String字符串内容不可变,一般存储内容不怎么发生变化的字符串。
(2)StringBuilder内容可变,内容如果经常变化,用StringBuidler效率高。
Java字符串String中使用==和equals有什么不同
答:
(1)==是比较两个字符串是不是同一个对象,是返回true,否则返回false。
(2)equals比较两个字符串的内容是否相同,是返回true,否则返回false。
Java语言中super类有哪些
答:
- 可以用在子类中,访问被子类隐藏父类中的成员变量和成员方法
- 置于子类构造方法第一句,调用父类的构造方法。
简述类的实例变量和静态变量的区别是什么
答:
- 类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;
- 实例变量则属对象私有,某一个对象将其值改变,不影响其他对象
举例说明方法参数传递中,传引用和传值的区别
答:
-
-
- 原始数据类型为传值,方法中对参数值的改变不会影响实参;
- 对象数据类型为传引用,方法中修改对象内容,则实参中会发现内容改变了。
-
简述一下Object类中的hashCode和equals方法。
答:
- hashCode() 方法用于返回对象的哈希码值,它返回的是一个整型值。这个哈希码值通常是根据对象的内存地址或者对象的字段计算而来的。
- equals() 方法用于比较对象是否相等。默认情况下,equals() 方法比较的是对象的引用,通常情况下,需要根据自定义类的业务逻辑重写 equals() 方法,以实现自定义的相等比较规则。
- 如果两个对象根据 equals() 方法是相等的,那么它们的 hashCode() 方法应该返回相同的值,通常,如果自定义类中重写了 equals() 方法,建议同时重写 hashCode() 方法。
什么是泛型类?请说明泛型类的用途。
答:
- 泛型类是一种具有泛型类型参数的类,即在类的定义中可以使用一个或多个类型参数,用来在类中定义字段、方法和构造函数等。
- 泛型类的主要用途有:提高代码的复用性,类型安全;避免类型转换。
请简述一下你对checked exception 和 unchecked exception的理解
答:
- Checked Exception ,受检异常,是在编译时由编译器强制检查的异常。程序必须显式地处理或者声明抛出这些异常,否则无法通过编译。通常是由外部因素导致,例如文件不存在、网络连接中断等,程序无法控制的异常情况。
- Unchecked Exception 是在运行时才会被检测到的异常,编译器不会强制要求对其进行处理或者声明抛出。通常是由程序错误导致。
叙述Java集合框架中Set 和 List的不同之处
答:
- Set 是无序的集合,不保证元素的顺序,同时不允许集合中存在重复的元素。
- List 是有序的集合,可以按照元素插入的顺序来访问和遍历集合中的元素。List 允许集合中存在重复的元素。
简述一下你对Arrays中的方法public static <T> void sort(T[] a, Comparator<? super T> c)的理解。
答:
- 该方法是一个可以对数组按指定比较器进行排序的泛型方法
- 第一个参数为任意对象类型的数组,第二个参数为比较器。
请说明一下你对JDK中Comparable接口和Comparator接口的理解。
答:
- Comparable 接口是 Java 提供的一个用于排序的接口,包含一个方法 compareTo,用于定义对象的自然排序顺序。
- Comparator 接口是用于定义对象排序比较逻辑的接口,包含一个方法 compare。
- 当类的排序逻辑无法通过实现 Comparable 接口中的 compareTo 方法来实现时,可以使用 Comparator 接口来定制排序规则。
Java中的缓冲流(Buffered Stream)是什么?它有什么优势?
答:
- 缓冲流(Buffered Stream)是Java中用于提高I/O操作性能的一种机制。它是通过在输入流(InputStream)或输出流(OutputStream)周围包装一个缓冲区(Buffer)来实现的。
- 缓冲流是一种性能优化的技术,通过内部的缓冲区来减少I/O操作次数,提高了数据读写的效率和性能。
请说出3个Java中常用的布局管理器?并简要说明它们的特点。
答:
Java中常用的布局管理器有FlowLayout、BorderLayout、GridLayout
- FlowLayout组件按照添加的顺序依次排列,默认从左到右,从上而下,居中排列。
- BorderLayout将组件分为5个区域:北、南、东、西和中,可以灵活控制组件的位置。
(3)GridLayout 可以将容器中的组件按照行和列来排列,每个单元格中都可以放置一个组件。
Java中常用的事件处理机制是什么?简要说明其工作原理。
答:
Java中常用的事件处理机制是基于事件监听器和事件源的模型。事件源表示能够发出事件的GUI组件,事件监听器则负责监听事件源发出的事件并执行相应的处理代码。当事件源上发生特定动作时,会触发相应的事件,监听器捕获该事件并执行相应的处理逻辑。通过注册对应的事件监听器到事件源上,可以实现事件和处理代码之间的绑定关系,从而实现事件驱动的交互式GUI编程。
二、编程题
编写Java代码,从键盘输入一个3x4的整数二维数组,并计算并打印出该二维数组每行元素的和,每列元素的和。
public class work1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[][] a = new int[3][4];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
a[i][j] = scanner.nextInt();
}
}
for (int i = 0; i < 3; i++) {
int rowSum = 0;
for (int j = 0; j < 4; j++) {
rowSum += a[i][j];
}
System.out.println("sum of elements in row" + (i + 1) + ":" + rowSum);
}
for (int i = 0; i < 4; i++) {
int colSum = 0;
for (int j = 0; j < 3; j++) {
colSum += a[j][i];
}
System.out.println("sum of elements in column" + (i + 1) + ":" + colSum);
}
scanner.close();
}
}
- 请定义两个类账号类(Account)和支票账号类(CheckingAccount),并满足如下要求(1)账号类有属性ID、户名(name)及账号余额;(2)账号类有一个全参构造方法;(3)账号类有一个抽象方法debit,表示从账号支取一定的金额;(4)支票账号类是账号类的子类,并具有一个表示每次交易的手续费(fee)的属性,手续费是一个固定值;(5)支票账号类有全参构造方法;(6)支票账号类实现了debit方法,每次交易会扣取手续费。
abstract class Account{
private String ID;
private String name;
private double balance;
public Account(String ID,String name,double balance){
this.ID=ID;
this.name=name;
this.balance=balance;
}
public double getBalance(){
return balance;
}
public void setBalance(double balance){
this.balance=balance;
}
public abstract boolean debit(double amount);
}
class CheckingAccount extends Account{
private double fee;
public CheckingAccount(String ID,String name,double balance,double fee){
super(ID,name,balance);
this.fee=fee;
}
public boolean debit(double amount){
if(getBalance()>amount+fee){
setBalance(getBalance()-amount-fee);
return true;
}else{
System.out.print("Debit amount exceeded account balance");
return false;
}
}
}
- 请定义一个矩形(Rectangle)类,矩形类满足下列要求:(1)矩形类有属性宽(width)和高(height);(2)矩形类有一个无参的构造方法和一个全参构造方法;(3)矩形类重载了equals方法;(4)矩形类具有按面积排序的自然序。
class Rectangle implements Comparable<Rectangle> {
private int width;
private int height;
public void Rectangle() {
}
public void Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public int hashCode() {
return Objects.hash(height, width);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || this.getClass() != o.getClass()) return false;
Rectangle other = (Rectangle) o;
return Double.compare(this.width, other.width) == 0 && Double.compare(this.height, other.height) == 0;
}
@Override
public int compareTo(Rectangle other) {
int thisArea = this.height * this.width;
int otherArea = other.height * other.width;
return Double.compare(thisArea, otherArea);
}
@Override
public String toString() {
return "Rectangle [width=" + width + ", height=" + height + "]";
}
}
- 编写一个投票统计程序,统计每个候选人的票数。投票情况可以存储在一个字符串数组中,如String[] votes = {“zhang”,”zhang”,”Li”,”Li”,”Wang”,”Li”,…}; 按票数多少顺序输出候选人姓名及其票数。
class work4 {
public static void main(String[] args) {
String[] votes = {"zhang", "zhang", "Li", "Li", "Wang", "Li", "Li"};
Map<String, Integer> voteCount = new HashMap<>();
for (String candidate : votes) {
Integer num = voteCount.get(candidate);
if (num == null) {
num = 1;
} else {
num = num + 1;
}
voteCount.put(candidate, num);
}
Set<Map.Entry<String, Integer>> entries = voteCount.entrySet();
List<Map.Entry<String, Integer>> list = new ArrayList<>(entries);
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue() - o1.getValue();
}
});
for (Map.Entry<String, Integer> entry : list) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
- 已知订单数据存储一个Object二维数组中,Object[][] orders ={{"饼干",15.88,10},{"面包",24.45,12},{"蛋糕",88.12,23}}。请使用DataOutputStream流将这些数据写入数据文件order.dat中。
public class WriterOrders {
static final String dataFile = "order.dat";
public static void main(String[] args)
throws FileNotFoundException, IOException {
Object[][] orders ={{"饼干",15.88,10},{"面包",24.45,12},{"蛋糕",88.12,23}}
DataOutputStream out = null;
try {
out = new DataOutputStream(new
BufferedOutputStream(new FileOutputStream(dataFile)));
for(Object[] order :orders){
out.writeUTF((String)order[0]);
out.writeDouble((Double)order[1]);
out.writeInt((int)order[2]);
}
} finally {
out.close();
}
}
}
- 已知order.dat中存放着若干订单数据,每条订单数据包括品名、单价、数量,创建该文件时,依次使用了DataOutputStream的writeUTF、writeDouble、writeInt方法写入这些数据项。请编写程序,将order.dat中的数据读出并打印到控制台。
public class ReadOrders {
static final String dataFile = "order.dat";
public static void main(String[] args) throws FileNotFoundException, IOException {
int a; )
double price;
String desc;
DataInputStream in = null;
in = new DataInputStream(
new BufferedInputStream(new FileInputStream(dataFile)));
try {
while (true) {
desc = in.readUTF();
System.out.print(desc+" ");
price = in.readDouble();
System.out.print(price+" ");
a = in.readInt();
System.out.println(a);
}
}catch(EOFException e){
e.printStackTrace();
} finally {
in.close();
}
}
}