个性化阅读
专注于IT技术分析

300个核心Java面试问题和答案(二)

本文概述


1 2 3 4 5


Java核心-OOP:多态性面试题


101)编译时多态和运行时多态有什么区别?

编译时多态和运行时多态之间存在以下差异。

SN compile-time polymorphism Runtime polymorphism
在编译时多态中, 对方法的调用在编译时解决。 在运行时多态中, 对覆盖方法的调用在运行时解决。
也称为静态绑定, 早期绑定或重载。 也称为动态绑定, 后期绑定, 重写或动态方法分派。
重载是一种实现编译时多态的方法, 其中, 我们可以定义具有不同签名的多个方法或构造函数。 覆盖是一种实现运行时多态的方法, 其中, 我们可以在派生类中重新定义一些特定的方法或变量。通过使用覆盖, 我们可以为派生类中的基类属性提供一些特定的实现。
因为对象的类型在编译时确定, 所以它提供了快速执行。 与编译时相比, 它提供了较慢的执行速度, 因为对象的类型是在运行时确定的。
编译时多态性提供的灵活性较差, 因为所有事物都在编译时解决。 运行时多态性提供了更大的灵活性, 因为所有事情都在运行时解决了。

102)什么是运行时多态?

运行时多态或动态方法分派是一个在运行时而不是在编译时解决对覆盖方法的调用的过程。在此过程中, 将通过超类的引用变量调用重写的方法。确定要调用的方法是基于参考变量所引用的对象。

class Bike{
   void run(){System.out.println("running");}
 }
 class Splendor extends Bike{
   void run(){System.out.println("running safely with 60km");}
   public static void main(String args[]){
     Bike b = new Splendor();//upcasting
     b.run();
   }
 }

立即测试

输出

running safely with 60km.

在此过程中, 将通过超类的引用变量调用重写的方法。确定要调用的方法是基于参考变量所引用的对象。

更多细节。


103)可以通过数据成员实现运行时多态吗?

不可以, 因为方法重写用于实现运行时多态并且不能重写数据成员。我们可以覆盖成员函数, 但不能覆盖数据成员。考虑下面给出的例子。

class Bike{
  int speedlimit=90;
 }
 class Honda3 extends Bike{
  int speedlimit=150;
  public static void main(String args[]){
   Bike obj=new Honda3();
   System.out.println(obj.speedlimit);//90
    }
}

立即测试

输出

90

更多细节。


104)静态绑定和动态绑定有什么区别?

在静态绑定的情况下, 对象的类型在编译时确定, 而在动态绑定中, 对象的类型在运行时确定。

静态绑定

class Dog{
 private void eat(){System.out.println("dog is eating...");}

 public static void main(String args[]){
  Dog d1=new Dog();
  d1.eat();
 }
}

动态绑定

class Animal{
 void eat(){System.out.println("animal is eating...");}
}

class Dog extends Animal{
 void eat(){System.out.println("dog is eating...");}

 public static void main(String args[]){
  Animal a=new Dog();
  a.eat();
 }
}

更多细节。


105)以下Java程序的输出是什么?

class BaseTest 
{
  void print()
  {
    System.out.println("BaseTest:print() called");
  }
}
public class Test extends BaseTest 
{
  void print() 
  {
    System.out.println("Test:print() called");
  }
  public static void main (String args[])
  {
    BaseTest b = new Test();
    b.print();
  }
}

输出

Test:print() called

解释

这是动态方法分派的一个示例。参考变量b的类型在运行时确定。在编译时, 将检查该方法是否存在于Base类中。在这种情况下, 它在子类中被覆盖, 因此, 在运行时将调用派生类方法。


106)什么是Java instanceOf运算符?

Java中的instanceof也称为类型比较运算符, 因为它会将实例与类型进行比较。它返回true或false。如果我们将instanceof运算符与任何具有空值的变量一起应用, 则它将返回false。考虑以下示例。

class Simple1{
 public static void main(String args[]){
 Simple1 s=new Simple1();
 System.out.println(s instanceof Simple1);//true
 }
}

立即测试

输出

true

子类类型的对象也是父类的类型。例如, 如果Dog扩展Animal, 则Dog或Animal类可以引用Dog的对象。


核心Java-OOPs概念:抽象面试问题


107)什么是抽象?

抽象是隐藏实现细节并仅向用户显示功能的过程。它仅向用户显示基本内容, 并隐藏内部信息, 例如, 在你键入文本并发送消息的位置发送SMS。你不知道有关邮件传递的内部处理。通过抽象, 你可以专注于对象的工作而不是对象的工作方式。抽象使你可以专注于对象的功能, 而不是对象的功能。

在Java中, 有两种方法可以实现抽象。

  • 抽象类
  • 接口

更多细节。


108)抽象和封装之间有什么区别?

抽象隐藏了实现细节, 而封装则将代码和数据包装到一个单元中。

更多细节。


109)什么是抽象类?

声明为抽象的类称为抽象类。它需要扩展并实现其方法。无法实例化。它可以具有抽象方法, 非抽象方法, 构造函数和静态方法。它还可以具有final方法, 这些方法将强制子类不更改方法的主体。考虑以下示例。

abstract class Bike{
   abstract void run();
 }
 class Honda4 extends Bike{
 void run(){System.out.println("running safely");}
 public static void main(String args[]){
  Bike obj = new Honda4();
  obj.run();
 }
 }

立即测试

输出

running safely

更多细节。


110)是否可以有没有抽象类的抽象方法?

不, 如果一个类中有一个抽象方法, 则该类必须是抽象的。


111)是否正确编写了以下程序?如果是, 那么程序的输出是什么?

abstract class Calculate
{
    abstract int multiply(int a, int b);
}
 
public class Main
{
    public static void main(String[] args)
    {
        int result = new Calculate()
        {    
            @Override
            int multiply(int a, int b)
            {
                return a*b;
            }
        }.multiply(12, 32);
        System.out.println("result = "+result);
    }
}

是的, 程序编写正确。 Main类提供了在抽象类Calculation中声明的乘法抽象方法的定义。该程序的输出将是:

输出

384

112)可以同时使用abstract和final两种方法吗?

不可以, 因为我们需要重写抽象方法以提供其实现, 而不能重写final方法。


113)可以实例化抽象类吗?

不可以, 即使抽象类包含构造函数并且其所有方法都已实现, 也永远无法实例化。


114)什么是接口?

该接口是具有静态常量和抽象方法的类的蓝图。它可以用于实现完全抽象和多重继承。这是一种实现抽象的机制。 Java接口中只能有抽象方法, 而方法主体则不能。它用于在Java中实现抽象和多重继承。换句话说, 可以说接口可以具有抽象方法和变量。 Java接口还表示IS-A关系。不能像抽象类一样实例化它。但是, 我们需要实现它以定义其方法。从Java 8开始, 我们可以在接口中使用默认, 静态和私有方法。

更多细节。


115)可以将接口方法声明为静态的吗?

不可以, 因为默认情况下接口的方法是抽象的, 并且我们不能同时使用静态和抽象。


116)接口可以是final的吗?

不可以, 因为一个接口需要由另一个类来实现, 并且如果它是final的, 则不能由任何一个类来实现。


117)什么是标记界面?

标记接口可以定义为没有数据成员和成员函数的接口。例如, Serializable, Cloneable是标记接口。标记接口可以声明如下。

public interface Serializable{  
}

118)抽象类和接口之间有什么区别?

Abstract class Interface
该接口只有抽象方法。
接口不能有实例变量。
接口不能具有构造函数。
接口不能具有静态方法。
你可以实现多个接口。
接口无法提供抽象类的实现。
interface关键字用于声明接口。
一个接口只能扩展另一个Java接口。
可以使用关键字工具来实现接口类
默认情况下, Java接口的成员是公共的。
示例:公共接口Drawable {void draw(); }

119)我们可以为接口中的成员定义私有和受保护的修饰符吗?

不, 它们是隐式公开的。


120)什么时候可以将对象引用转换为接口引用?

当对象实现引用的接口时, 可以将对象引用转换为接口引用。


121)如何用Java制作只读类?

通过将所有字段设为私有可以将类设为只读。只读类仅具有getter方法, 该方法会将类的private属性返回给main方法。我们无法修改此属性, 因为该类中没有可用的setter方法。考虑以下示例。

//A Java class which has only getter methods.  
public class Student{  
//private data member  
private String college="AKG";  
//getter method for college  
public String getCollege(){  
return college;  
}  
}

122)如何用Java编写只写类?

通过将所有字段设为私有, 可以将类设为只写。只写类将仅具有setter方法, 该方法将设置从main方法传递到私有字段的值。我们无法读取该类的属性, 因为此类中没有getter方法。考虑以下示例。

//A Java class which has only setter methods.  
public class Student{  
//private data member  
private String college;  
//getter method for college  
public void setCollege(String college){  
this.college=college;  
}  
}

123)Java封装的优点是什么?

Java封装具有以下优点?

  • 通过仅提供setter或getter方法, 可以使该类为只读或仅写。换句话说, 你可以跳过getter或setter方法。
  • 它为你提供了对数据的控制。假设你要设置的id值仅应大于100, 你可以在setter方法中编写逻辑。你可以编写不将负数存储在setter方法中的逻辑。
  • 这是一种在Java中实现数据隐藏的方法, 因为其他类将无法通过私有数据成员访问数据。
  • 封装类易于测试。因此, 最好是进行单元测试。
  • 标准的IDE提供了生成getter和setter的工具。因此, 使用Java创建封装类非常容易且快速。

核心Java-OOPs概念:软件包面试问题


124)包装是什么?

包是一组相似类型的类, 接口和子包。它提供访问保护并消除命名冲突。 Java中的软件包可以分为两种形式:内置软件包和用户定义的软件包。有许多内置包, 例如Java, lang, awt, javax, swing, net, io, util, sql等。请考虑以下示例, 以Java创建包。

//save as Simple.java
package mypack;
public class Simple{
 public static void main(String args[]){
    System.out.println("Welcome to package");
   }
}
用Java打包

更多细节。


125)用Java定义包的优点是什么?

通过定义包, 我们可以避免在不同包中定义的相同类名之间的名称冲突。软件包还使开发人员可以更有效地组织相似的类。例如, 可以清楚地了解java.io包中存在的类用于执行与io相关的操作。


126)如何用Java创建包?

如果你使用的是Eclipse, NetBeans, MyEclipse等编程IDE, 请单击文件->新建->项目, 然后eclipse会要求你输入软件包的名称。它将创建包含各种目录(例如src等)的项目包。如果你正在使用记事本之类的编辑器进行Java编程, 请使用以下步骤创建包。

定义一个包package_name。创建名为class_name的类, 并使用your_class_name.java保存此文件。

现在, 通过在终端上运行以下命令来编译文件。

javac -d . your_class_name.java

上面的命令在当前工作目录中创建名为package_name的软件包。

现在, 使用绝对类文件名运行类文件, 如下所示。

java package_name.class_name

127)如何使用Java访问另一个类中的某个类?

有两种方法可以访问另一个类中的一个类。

  • 通过使用完全限定名称:要访问其他包中的类, 我们必须使用该类的完全限定名称, 或者必须导入包含该类的包。
  • 通过使用相对路径, 我们可以使用与包含我们的类的包相关的类的路径。它可以相同或子包。

128)我是否需要随时导入java.lang包?为什么?

否。默认情况下, 它是由JVM内部加载的。


129)我可以两次导入同一包/类吗? JVM是否会在运行时两次加载软件包?

一个人可以多次导入同一包或同一类。编译器和JVM都没有抱怨它。但是, 无论你导入同一类多少次, JVM都会在内部仅一次加载该类。


130)什么是静态导入?

通过静态导入, 我们可以直接访问类的静态成员, 而没有使用类名来限定它的权限。

更多细节。


Java:异常处理面试问题

提供了一个例外处理面试问题及其答案的列表。如果你知道任何处理面试问题的例外情况, 请将其张贴在评论部分。


131)Java程序中可以发生几种异常类型?

主要有两种类型的异常:选中和未选中。在这里, 错误被视为未检查的异常。根据Oracle, 有三种类型的异常:

检查异常:检查异常是在编译时检查的异常。例如, SQLException, ClassNotFoundException等。

未检查的异常:未检查的异常是在运行时处理的异常, 因为它们不能在编译时进行检查。例如, ArithmaticException, NullPointerException, ArrayIndexOutOfBoundsException等。

错误:错误导致程序退出, 因为它们不可恢复。例如, OutOfMemoryError, AssertionError等。


132)什么是异常处理?

异常处理是一种用于处理运行时错误的机制。它主要用于处理检查的异常。异常处理保持程序的正常流程。主要有两种类型的异常:选中和未选中。在这里, 该错误被视为未经检查的异常。

更多细节。


133)解释Java异常类的层次结构吗?

java.lang.Throwable类是Java异常层次结构的根类, 它由两个子类继承:异常和错误。 Java异常类的层次结构如下:

异常处理的层次结构

134)Checked Exception和Unchecked Exception有什么区别?

1)检查异常

除RuntimeException和Error外, 扩展Throwable类的类称为检查异常, 例如IOException, SQLException等。检查异常在编译时检查。

2)未检查的异常

扩展RuntimeException的类称为未检查的异常, 例如ArithmeticException, NullPointerException等。在编译时不会检查未检查的异常。

更多细节。


135)错误和异常的基类是什么?

Throwable类是Error和Exception的基类。


136)是否有必要在每个try块之后都添加catch块?

不必在每个try块之后都必须跟随catch块。它后面应该是catch块或finally块。因此, 应该在方法的throws子句中声明任何可能引发的异常。考虑以下示例。

public class Main{
     public static void main(String []args){
        try{
            int a = 1; 
            System.out.println(a/0);
        }
        finally
        {
            System.out.println("rest of the code...");
        }
     }
}

输出

Exception in thread main java.lang.ArithmeticException:/ by zero
rest of the code...

137)以下Java程序的输出是什么?

public class ExceptionHandlingExample {
public static void main(String args[])
{
	try
	{
		int a = 1/0;
		System.out.println("a = "+a);
	}
	catch(Exception e){System.out.println(e);}
	catch(ArithmeticException ex){System.out.println(ex);}	
}
}

输出

ExceptionHandlingExample.java:10: error: exception ArithmeticException has already been caught
	catch(ArithmeticException ex){System.out.println(ex);}	
	^
1 error

解释

ArithmaticException是Exception的子类。因此, 不能在Exception之后使用它。由于Exception是所有异常的基类, 因此, 必须最后使用它来处理该异常。此后不能使用任何类。


138)final是什么?

“final”块用于执行程序的重要代码。无论是否处理异常都将执行。换句话说, 可以说finally块是始终执行的块。最后, 块跟随try或catch块。如果不处理该异常, 则在终止程序之前, JVM将运行finally块(如果有)。 finally块主要用于放置清除代码, 例如关闭文件或关闭连接。在这里, 我们必须知道, 对于每个try块, 可以有零个或多个catch块, 但只有一个finally块。如果程序退出(通过调用System.exit()或导致导致进程中止的致命错误), 则不会执行finally块。

finally java

更多细节。


139)可以在没有阻碍的情况下final使用块吗?

是的, 根据finally块的定义, 必须在其后跟随try或catch块, 因此, 我们可以使用try块代替catch。更多细节。


140)是否有什么情况下final将不会执行?

如果程序退出(通过调用System.exit()或引起致命错误并导致进程中止), 则不会执行finally块。更多详细信息。


141)throw和throws有什么区别?

throw keyword throws keyword
throws关键字用于声明异常。
可以使用throws传播检查的异常
throws关键字之后是类。
throws关键字与方法签名一起使用。
你可以声明多个异常, 例如, public void method()引发IOException, SQLException。

更多细节。


142)以下Java程序的输出是什么?

public class Main{
     public static void main(String []args){
        try
        {
            throw 90; 
        }
        catch(int e){
            System.out.println("Caught the exception "+e);
        }
            
    }
}

输出

Main.java:6: error: incompatible types: int cannot be converted to Throwable
            throw 90; 
            ^
Main.java:8: error: unexpected type
        catch(int e){
              ^
  required: class
  found:    int
2 errors

解释

在Java中, 只能抛出可抛出对象。如果尝试抛出整数对象, 则编译器将显示错误, 因为我们无法抛出代码块中的基本数据类型。


143)以下Java程序的输出是什么?

class Calculation extends Exception
{
    public Calculation() 
    {
        System.out.println("Calculation class is instantiated");
    }
    public void add(int a, int b)
    {
        System.out.println("The sum is "+(a+b));
    }
}
public class Main{
     public static void main(String []args){
        try
        {
            throw new Calculation(); 
        }
        catch(Calculation c){
            c.add(10, 20);
        }
    }
}

输出

Calculation class is instantiated
The sum is 30

解释

从catch块中捕获的try块抛出了Calculation对象。通过使用此类的对象, 可以使用整数值10和20调用Calculation类的add()。因此, 打印了总和30。仅当对象的类型可抛出时, 才可以抛出Main类的对象。为此, 我们需要扩展throwable类。


144)可以重新抛出异常吗?

是。


145)如果父类方法没有引发异常, 则子类重写方法可以声明异常吗?

是, 但仅未检查的异常未检查。

更多细节。


146)什么是异常传播?

首先从堆栈的顶部抛出一个异常, 如果未捕获到异常, 则将调用堆栈降到先前的方法, 如果未捕获到那里, 则异常再次下降到先前的方法, 依此类推, 直到被捕获为止。被捕获或直到它们到达调用堆栈的最底端。此过程称为异常传播。默认情况下, 不传播检查的异常。

class TestExceptionPropagation1{
  void m(){
    int data=50/0;
  }
  void n(){
    m();
  }
  void p(){
   try{
    n();
   }catch(Exception e){System.out.println("exception handled");}
  }
  public static void main(String args[]){
   TestExceptionPropagation1 obj=new TestExceptionPropagation1();
   obj.p();
   System.out.println("normal flow...");
  }
}

立即测试

输出

exception handled
normal flow...
异常传播

更多细节。




147)以下Java程序的输出是什么?

public class Main 
{
    void a()
    {
        try{
        System.out.println("a(): Main called");
        b();
        }catch(Exception e)
        {
            System.out.println("Exception is caught");
        }
    }
    void b() throws Exception
    {
     try{
         System.out.println("b(): Main called");
         c();
     }catch(Exception e){
         throw new Exception();
     }
     finally 
     {
         System.out.println("finally block is called");
     }
    }
    void c() throws Exception 
    {
        throw new Exception();
    }

    public static void main (String args[])
    {
        Main m = new Main();
        m.a();
    }
}

输出

a(): Main called
b(): Main called
finally block is called
Exception is caught

解释

在main方法中, 调用Main的a()来打印消息并调用b()。方法b()打印一些消息, 然后调用c()。方法c()引发一个异常, 该异常由方法b的catch块处理。但是, 它通过使用由方法a()处理的throw Exception()传播此异常。众所周知, finally块总是执行的, 因此方法b()中的finally块将首先执行并输出一条消息。最后, 异常由方法a()的catch块处理。


148)以下Java程序的输出是什么?

public class Calculation 
{
    int a; 
    public Calculation(int a)
    {
        this.a = a;
    }
    public int add()
    {
        a = a+10; 
        try 
        {
            a = a+10; 
            try 
            {
                a = a*10; 
                throw new Exception(); 
            }catch(Exception e){
                a = a - 10;
            }
        }catch(Exception e)
        {
            a = a - 10; 
        }
        return a;
    }
    
    public static void main (String args[])
    {
        Calculation c = new Calculation(10);
        int result = c.add();
        System.out.println("result = "+result);
    }
}

输出

result = 290

解释

使用实例化该类时调用的类构造函数, 将Calculation类的实例变量a初始化为10。调用add方法, 该方法返回整数值结果。在add()方法中, a增加10到20。然后, 在第一个try块中, 10再次增加10到30。在第二try块中, a乘10到300。 try块引发与该try块关联的catch块捕获的异常。 catch块通过将a的值减10以使其变为290, 从而再次更改a的值。因此, add()方法返回290, 该结果被分配给result。但是, 与最外层try块相关联的catch块将永远不会执行, 因为没有任何异常可以由该catch块处理。


Java:字符串处理面试问题

给出了带有简短答案和针对性答案的字符串处理面试问题列表。如果你知道任何字符串处理面试问题, 请将其张贴在评论部分。


149)什么是字符串池?

字符串池是堆内存中保留的空间, 可用于存储字符串。使用字符串池的主要优点是每当我们创建字符串文字时; JVM首先检查”字符串常量池”。如果该字符串已经存在于池中, 则返回对该池实例的引用。如果该字符串在池中不存在, 则会创建一个新的字符串实例并将其放置在池中。因此, 它通过避免重复来节省内存。

Java字符串文字

150)关于String不变的含义是什么?

不可变的简单含义是不可更改或不可更改的。在Java中, String是不可变的, 即, 一旦创建了字符串对象, 就无法更改其值。请考虑以下示例, 以更好地理解。

class Testimmutablestring{
 public static void main(String args[]){
   String s="Sachin";
   s.concat(" Tendulkar");//concat() method appends the string at the end
   System.out.println(s);//will print Sachin because strings are immutable objects
 }
}

立即测试

输出

Sachin

更多细节。


151)为什么对象在Java中是不可变的?

因为Java使用字符串文字的概念。假设有五个参考变量, 全部引用一个对象” sachin”。如果一个参考变量更改了对象的值, 它将受到所有参考变量的影响。这就是为什么字符串对象在Java中是不可变的。

堆图

更多细节。


152)我们可以用几种方法创建字符串对象?

1)字符串文字

Java字符串文字是使用双引号创建的。例如:

String s="welcome";

每次创建字符串文字时, JVM都会首先检查”字符串常量池”。如果该字符串已经存在于池中, 则返回对该池实例的引用。如果该字符串在池中不存在, 则会创建一个新的字符串实例并将其放置在池中。字符串对象存储在称为字符串常量池的特殊存储区中, 例如:

String s1="Welcome";
String s2="Welcome";//It doesn't create a new instance

2)通过新关键字

String s=new String("Welcome");//creates two objects and one reference variable

在这种情况下, JVM将在普通(非池)堆内存中创建一个新的字符串对象, 而文字” Welcome”将放置在常量字符串池中。变量s引用堆(非池)中的对象。


153)在下面的代码中将创建多少个对象?

String s1="Welcome";
String s2="Welcome";
String s3="Welcome";

使用上述代码只能创建一个对象, 因为Java中的字符串是不可变的。

更多细节。


154)为什么Java使用字符串文字的概念?

使Java的内存使用效率更高(因为如果字符串常量池中已经存在新对象, 则不会创建新对象)。

更多细节。


155)在下面的代码中将创建多少个对象?

String s = new String("Welcome");

两个对象, 一个在字符串常量池中, 另一个在非池(堆)中。

更多细节。


156)以下Java程序的输出是什么?

public class Test 
{
    public static void main (String args[])
    {
        String a = new String("Sharma is a good player");
        String b = "Sharma is a good player";
        if(a == b)
        {
            System.out.println("a == b");
        }
        if(a.equals(b))
        {
            System.out.println("a equals b");
        }
    }
}

输出

a equals b

解释

运算符==还检查两个字符串对象的引用是否相等。尽管两个字符串都包含相同的内容, 但是它们的引用并不相等, 因为它们都是通过不同的方式(构造函数和字符串文字)创建的, 因此a == b是不相等的。另一方面, equal()方法始终检查内容。由于它们的内容相等, 因此将打印a等于b。


157)以下Java程序的输出是什么?

public class Test 
{
    public static void main (String args[])
    {
        String s1 = "Sharma is a good player";
        String s2 = new String("Sharma is a good player");
        s2 = s2.intern();
        System.out.println(s1 ==s2);
    }
}

输出

true

解释

intern方法从字符串池返回String对象引用。在这种情况下, 使用字符串文字创建s1, 而使用字符串池创建s2。但是, 将s2更改为s1的参考, 并且运算符==返回true。


158)String和StringBuffer有什么区别?

下表列出了String和StringBuffer之间的区别。

No. String StringBuffer
String类是不可变的。 StringBuffer类是可变的。
当你连接太多字符串时, String速度很慢, 并且会占用更多内存, 因为每次创建新实例时, String都会出现。 当你可以分配字符串时, StringBuffer速度很快并且消耗的内存更少。
String类重写Object类的equals()方法。因此, 你可以通过equals()方法比较两个字符串的内容。 StringBuffer类不会覆盖Object类的equals()方法。

159)StringBuffer和StringBuilder有什么区别?

下面给出了StringBuffer和StringBuilder之间的区别。

No. StringBuffer StringBuilder
StringBuffer已同步, 即线程安全。这意味着两个线程不能同时调用StringBuffer的方法。 StringBuilder是不同步的, 即不是线程安全的。这意味着两个线程可以同时调用StringBuilder的方法。
StringBuffer的效率不如StringBuilder。 StringBuilder比StringBuffer效率更高。

160)我们如何用Java创建不可变的类?

我们可以通过定义一个将所有成员作为final的final类来创建一个不可变的类。考虑以下示例。

public final class Employee{
final String pancardNumber;

public Employee(String pancardNumber){
this.pancardNumber=pancardNumber;
}

public String getPancardNumber(){
return pancardNumber;
}

}

更多细节。


161)Java中toString()方法的目的是什么?

toString()方法返回对象的字符串表示形式。如果打印任何对象, 则Java编译器会在内部调用该对象的toString()方法。因此, 覆盖toString()方法, 返回所需的输出, 它可以是对象的状态, 依此类推, 具体取决于你的实现。通过重写Object类的toString()方法, 我们可以返回对象的值, 因此不需要编写太多代码。考虑以下示例。

class Student{
 int rollno;
 String name;
 String city;

 Student(int rollno, String name, String city){
 this.rollno=rollno;
 this.name=name;
 this.city=city;
 }
 
 public String toString(){//overriding the toString() method
  return rollno+" "+name+" "+city;
 }
 public static void main(String args[]){
   Student s1=new Student(101, "Raj", "lucknow");
   Student s2=new Student(102, "Vijay", "ghaziabad");
   
   System.out.println(s1);//compiler writes here s1.toString()
   System.out.println(s2);//compiler writes here s2.toString()
 }
}

输出

101 Raj lucknow
102 Vijay ghaziabad

更多细节。


162)为什么用CharArray()而不是String来存储密码?

字符串保留在字符串池中, 直到收集垃圾为止。如果我们将密码存储在字符串中, 则它会在内存中保留更长的时间, 任何拥有内存转储的人都可以将密码提取为明文。另一方面, 使用CharArray允许我们在完成密码后将其设置为空白。通过使我们能够控制内存, 它避免了字符串带来的安全威胁。


163)编写一个Java程序来计算字符串中存在的单词数?

程序:

public class Test 
{
    public static void main (String args[])
    {
        String s = "Sharma is a good player and he is so punctual";
        String words[] = s.split(" ");
        System.out.println("The Number of words present in the string are : "+words.length);
    }
}

输出

The Number of words present in the string are : 10

164)命名java.util.regex包中存在的一些类。

java.util.regex软件包中存在以下类和接口。

  • MatchResult介面
  • 比赛班
  • 模式类
  • PatternSyntaxException类
Java Regex API

165)元字符与普通字符有何不同?

元字符对正则表达式引擎具有特殊含义。元字符是^, $, 。, *, +等。正则表达式引擎不会将它们视为正则字符。为了使正则表达式引擎将元字符视为普通字符, 我们需要使用反斜杠对元字符进行转义。


166)编写正则表达式以验证密码。密码必须以字母开头, 后跟字母数字字符。长度必须在8到20之间。

上述标准的正则表达式为:^ [a-zA-Z] [a-zA-Z0-9] {8, 19}其中^表示正则表达式的开始, [a-zA-Z]表示第一个字符必须是字母, [a-zA-Z0-9]代表字母数字字符, {8, 19}代表密码的长度必须在8到20之间。


167)以下Java程序的输出是什么?

import java.util.regex.*;
class RegexExample2{
public static void main(String args[]){
System.out.println(Pattern.matches(".s", "as")); //line 4
System.out.println(Pattern.matches(".s", "mk")); //line 5 
System.out.println(Pattern.matches(".s", "mst")); //line 6
System.out.println(Pattern.matches(".s", "amms")); //line 7
System.out.println(Pattern.matches("..s", "mas")); //line 8
}}

输出

true
false 
false
false 
true

解释

由于字符串的第二个字符是s, 所以第4行显示true;由于第二个字符不是s, 第5行显示false;由于字符串中有3个以上字符, 因此第6行显示false;由于第2个字符中有2个以上, 因此第7行显示false字符串中的第三个字符为s, 并且该字符串还包含两个以上的字符, 第8行显示true。


Java核心:嵌套类和接口面试问题


168)Java内部类的优点是什么?

Java内部类有两种优点。

  • 嵌套类代表一种特殊的关系, 它可以访问外部类的所有成员(数据成员和方法), 包括私有。
  • 嵌套类用于开发更具可读性和可维护性的代码, 因为它在逻辑上仅将类和接口组合在一个位置。
  • 代码优化:需要更少的代码来编写。

169)什么是嵌套类?

嵌套类可以定义为在另一个类或接口内部定义的类。我们使用嵌套类在一个位置上对类和接口进行逻辑分组, 以使其更具可读性和可维护性。嵌套类可以访问外部类的所有数据成员, 包括私有数据成员和方法。嵌套类的语法在下面定义。

class Java_Outer_class{  
 //code  
 class Java_Nested_class{  
  //code  
 }  
}

嵌套类有两种类型, 静态嵌套类和非静态嵌套类。非静态嵌套类也可以称为内部类

更多细节。


170)使用内部类的缺点是什么?

使用内部类有以下主要缺点。

  • 内部类增加了开发人员使用的类总数, 因此增加了JVM的工作量, 因为JVM必须对那些额外的类执行一些常规操作, 这会导致性能降低。
  • 与顶级类相比, IDE对内部类的支持较少, 因此, 开发人员在使用内部类时会感到烦恼。

171)Java中使用的内部类(非静态嵌套类)的类型是什么?

Java中主要使用三种类型的内部类。

Type Description
在类内部和外部方法中创建的类。
为实现接口或扩展类而创建的类。它的名称由java编译器决定。
在方法内创建的类。

172)嵌套类和内部类之间是否有区别?

是的, 内部类是非静态嵌套类。换句话说, 我们可以说内部类是嵌套类的一部分。

更多细节。


173)我们可以在局部内部类内部访问非final局部变量吗?

不, 如果要在本地内部类中访问它, 则本地变量必须是常量。

更多细节。


174)在以下程序中, 编译OuterClass时会创建多少个类文件?

public class Person {
String name, age, address;
class Employee{
  float salary=10000;
}
class BusinessMen{
  final String gstin="£4433drt3$"; 
}
public static void main (String args[])
{
  Person p = new Person();
}
}

将创建3个类文件, 分别命名为Person.class, Person $ BusinessMen.class和Person $ Employee.class。


175)什么是匿名内部类?

匿名内部类是在表达式中自动声明和实例化的类。我们不能对它们应用不同的访问修饰符。匿名类不能是静态的, 也不能定义任何静态字段, 方法或类。换句话说, 我们可以说它是一个没有名称的类, 并且只能有一个由其定义创建的对象。考虑以下示例。

abstract class Person{
  abstract void eat();
}
class TestAnonymousInner{
 public static void main(String args[]){
  Person p=new Person(){
  void eat(){System.out.println("nice fruits");}
  };
  p.eat();
 }
}

立即测试

输出

nice fruits

考虑下面的示例, 以使用接口工作匿名类。

interface Eatable{
 void eat();
}
class TestAnnonymousInner1{
 public static void main(String args[]){
 Eatable e=new Eatable(){
  public void eat(){System.out.println("nice fruits");}
 };
 e.eat();
 }
}

立即测试

输出

nice fruits

176)什么是嵌套接口?

在接口或类内部声明的接口称为嵌套接口。默认情况下是静态的。嵌套接口用于对相关接口进行分组, 以便于维护。外部接口或类必须引用嵌套接口。不能直接访问。如果嵌套接口在接口内声明, 则该接口必须是公共的, 但如果在类内声明, 则可以具有任何访问修饰符。嵌套接口的语法如下。

interface interface_name{  
 ...  
 interface nested_interface_name{  
  ...  
 }  
}

更多细节。


177)一个类可以有一个接口吗?

是的, 可以在类中定义接口。它称为嵌套接口。

更多细节。


178)接口可以有一个类吗?

是的, 它们隐式地是静态的。

更多细节。

垃圾收集面试问题


179)什么是垃圾回收?

垃圾回收是回收未使用的运行时对象的过程。进行内存管理。换句话说, 我们可以说这是从内存中删除未使用的对象以释放空间并使该空间可用于Java虚拟机的过程。由于垃圾回收, java将0设置为未设置值的变量的输出, 即该变量已定义但尚未初始化。为此, 我们在C语言中使用free()函数, 在C ++中使用delete()。在Java中, 它是自动执行的。因此, java提供了更好的内存管理。

更多细节。


180)什么是gc()?

gc()方法用于调用垃圾收集器进行清理处理。在System和Runtime类中可以找到此方法。该函数显式地使Java虚拟机释放未使用对象占用的空间, 以便可以利用或重用它。考虑以下示例, 以更好地了解gc()方法如何调用垃圾回收器。

public class TestGarbage1{
 public void finalize(){System.out.println("object is garbage collected");}
 public static void main(String args[]){
  TestGarbage1 s1=new TestGarbage1();
  TestGarbage1 s2=new TestGarbage1();
  s1=null;
  s2=null;
  System.gc();
 }
}

立即测试

object is garbage collected
       object is garbage collected

181)如何控制垃圾收集?

垃圾收集由JVM管理。当内存中没有足够的空间并且内存不足时执行此操作。我们可以从外部调用System.gc()进行垃圾回收。但是, 是否执行它取决于JVM。


182)如何取消引用对象?

有很多方法:

  • 通过取消引用
  • 通过分配对另一个的引用
  • 通过匿名对象等
Java垃圾回收场景

1)通过取消引用:

Employee e=new Employee();
e=null;

2)通过分配对另一个的引用:

Employee e1=new Employee();
Employee e2=new Employee();
e1=e2;//now the first object referred by e1 is available for garbage collection

3)通过匿名对象:

new Employee();

183)finalize()方法的目的是什么?

finalize()方法在对象被垃圾回收之前被调用。用于执行清理处理。 JVM的垃圾收集器仅收集那些由new关键字创建的对象。因此, 如果创建的对象没有新对象, 则可以使用finalize方法执行清理处理(销毁剩余的对象)。清理过程是释放所有以前使用且不再需要的资源, 网络的过程。必须记住, 它不是保留关键字, finalize方法存在于对象类中, 因此它在每个类中都可用, 因为对象类是Java中每个类的超类。在这里, 我们必须注意, 终结和垃圾回收都不被保证。考虑以下示例。

public class FinalizeTest {
	int j=12;
	void add()
	{
		j=j+12;
		System.out.println("J="+j);
	}
	public void finalize()
	{
		System.out.println("Object is garbage collected");
	}
	public static void main(String[] args) {
		new FinalizeTest().add();
		System.gc();
		new FinalizeTest().add();
	}
}

184)是否可以再次引用未引用的对象?

是,


185)垃圾收集器线程是哪种线程?

守护程序线程。


186)final, final和finalize有什么区别?

No. final finally finalize
Final用于对类, 方法和变量施加限制。 final类不能被继承, final方法不能被覆盖, final变量值不能被改变。 finally用于放置重要代码, 无论是否处理异常, 都将执行该代码。 Finalize用于在垃圾回收对象之前执行清理处理。
Final是一个关键字。 finally是一个块。 完成是一种方法。

187)运行时类的目的是什么?

Java Runtime类用于与Java运行时环境进行交互。 Java Runtime类提供了执行进程, 调用GC, 获取总内存和可用内存等的方法。java.lang.Runtime类只有一个实例可用于一个Java应用程序。 Runtime.getRuntime()方法返回Runtime类的单例实例。


188)你将如何调用Java中的任何外部进程?

通过Runtime.getRuntime()。exec(?)方法。考虑以下示例。

public class Runtime1{
 public static void main(String args[])throws Exception{
  Runtime.getRuntime().exec("notepad");//will open a new notepad
 }
}

I / O面试问题


189)给出InputStream和OutputStream类的层次结构。

OutputStream层次结构

Java输出流层次结构

InputStream层次结构

Java输入流层次结构

190)你对IO流了解什么?

流是从源流向目的地的一系列数据。它由字节组成。在Java中, 会自动为我们创建三个流。

  • System.out:标准输出流
  • System.in:标准输入流
  • System.err:标准错误流

191)Reader / Writer类层次结构和InputStream / OutputStream类层次结构之间有什么区别?

Reader / Writer类层次结构是面向字符的, 而InputStream / OutputStream类层次结构是面向字节的。 ByteStream类用于执行8位字节的输入-输出, 而CharacterStream类用于执行16位Unicode系统的输入/输出。 ByteStream类层次结构中有许多类, 但是最常用的类是FileInputStream和FileOutputStream。最常用的类CharacterStream类层次结构是FileReader和FileWriter。


192)所有流的超级类最多是什么?

所有流类都可以分为ByteStream类和CharacterStream类两种类型。 ByteStream类进一步分为InputStream类和OutputStream类。 CharacterStream类也分为Reader类和Writer类。所有InputStream类的SuperMost类为java.io.InputStream, 所有输出流类的SuperMost类为java.io.OutPutStream。同样, 对于所有阅读器类, 最高级的类是java.io.Reader, 而对于所有书写器类, 它的均是java.io.Writer。


193)什么是FileInputStream和FileOutputStream?

Java FileOutputStream是用于将数据写入文件的输出流。如果你有一些原始值要写入文件, 请使用FileOutputStream类。你可以通过FileOutputStream类编写面向字节的数据和面向字符的数据。但是, 对于面向字符的数据, 首选使用FileWriter而不是FileOutputStream。考虑以下将字节写入文件的示例。

import java.io.FileOutputStream;  
public class FileOutputStreamExample {  
    public static void main(String args[]){    
           try{    
             FileOutputStream fout=new FileOutputStream("D:\testout.txt");    
             fout.write(65);    
             fout.close();    
             System.out.println("success...");    
            }catch(Exception e){System.out.println(e);}    
      }    
}

Java FileInputStream类从文件获取输入字节。它用于读取面向字节的数据(原始字节流), 例如图像数据, 音频, 视频等。你还可以读取字符流数据。但是, 为了读取字符流, 建议使用FileReader类。考虑以下示例从文件读取字节。

import java.io.FileInputStream;  
public class DataStreamExample {  
     public static void main(String args[]){    
          try{    
            FileInputStream fin=new FileInputStream("D:\testout.txt");    
            int i=fin.read();  
            System.out.print((char)i);    
  
            fin.close();    
          }catch(Exception e){System.out.println(e);}    
         }    
        }

194)使用BufferedInputStream和BufferedOutputStream类的目的是什么?

Java BufferedOutputStream类用于缓冲输出流。它在内部使用缓冲区存储数据。与将数据直接写入流相比, 它提高了效率。因此, 它可以提高性能。而Java BufferedInputStream类用于从流中读取信息。它在内部使用缓冲机制来提高性能。


195)如何在Java中设置文件的权限?

在Java中, FilePermission类用于更改文件上的权限集。 Java FilePermission类包含与目录或文件相关的权限。所有权限都与路径相关。路径可以有两种类型:

  • D:\\ IO \\-:表示该权限与所有子目录和文件都递归关联。
  • D:\\ IO \\ *:表示该权限与该目录中的所有目录和文件(子目录除外)相关联。

让我们看一个简单的示例, 其中授予目录路径权限和读取权限, 并授予该目录文件的写入权限。

package com.srcmini;
import java.io.*;
import java.security.PermissionCollection;
public class FilePermissionExample{
     public static void main(String[] args) throws IOException {
      String srg = "D:\IO Package\java.txt";
      FilePermission file1 = new FilePermission("D:\IO Package\-", "read");
      PermissionCollection permission = file1.newPermissionCollection();
      permission.add(file1);
           FilePermission file2 = new FilePermission(srg, "write");
           permission.add(file2);
         if(permission.implies(new FilePermission(srg, "read, write"))) {
           System.out.println("Read, Write permission is granted for the path "+srg );
             }else {
            System.out.println("No Read, Write permission is granted for the path "+srg);            }
     } 
}

输出

Read, Write permission is granted for the path D:\IO Package\java.txt

196)什么是FilterStreams?

FilterStream类用于向其他流类添加其他功能。 FilterStream类的作用类似于接口, 该接口从流中读取数据, 对其进行过滤, 然后将过滤后的数据传递给调用方。 FilterStream类提供了额外的功能, 例如将行号添加到目标文件等。


197)什么是I / O过滤器?

I / O过滤器是一个对象, 它从一个流读取并写入另一个流, 通常在将数据从一个流传递到另一流时以某种方式更改数据。许多Filter类允许用户使用多个输入流建立链。它在多个滤镜上产生组合效果。


198)在Java中, 你可以通过几种方式从控制台获取输入?

在Java中, 可以使用三种方式从控制台获取输入。

使用BufferedReader类:通过将System.in包装到InputStreamReader中并将其传递到BufferedReader中, 我们可以从控制台获取输入。当输入被缓冲时, 它提供了有效的读数。考虑以下示例。

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
public class Person 
{ 
    public static void main(String[] args) throws IOException  
    { 
      System.out.println("Enter the name of the person");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
        String name = reader.readLine(); 
        System.out.println(name);         
    } 
}

使用Scanner类:Java Scanner类使用默认为空格的定界符将输入分为令牌。它提供了许多读取和解析各种原始值的方法。 Java Scanner类广泛用于使用正则表达式解析文本以获取字符串和原始类型。 Java Scanner类扩展了Object类, 并实现了Iterator和Closeable接口。考虑以下示例。

import java.util.*;  
public class ScannerClassExample2 {    
      public static void main(String args[]){                       
          String str = "Hello/This is srcmini/My name is Abhishek.";  
          //Create scanner with the specified String Object  
          Scanner scanner = new Scanner(str);  
          System.out.println("Boolean Result: "+scanner.hasNextBoolean());            
          //Change the delimiter of this scanner  
          scanner.useDelimiter("/");  
          //Printing the tokenized Strings  
          System.out.println("---Tokenizes String---");   
        while(scanner.hasNext()){  
            System.out.println(scanner.next());  
        }  
          //Display the new delimiter  
          System.out.println("Delimiter used: " +scanner.delimiter());            
          scanner.close();  
          }    
}

使用控制台类:Java控制台类用于从控制台获取输入。它提供了读取文本和密码的方法。如果使用Console类读取密码, 则不会向用户显示该密码。 java.io.Console类在内部连接到系统控制台。从1.5开始引入Console类。考虑以下示例。

import java.io.Console;  
class ReadStringTest{    
public static void main(String args[]){    
Console c=System.console();    
System.out.println("Enter your name: ");    
String n=c.readLine();    
System.out.println("Welcome "+n);    
}    
}

序列化面试问题


199)什么是序列化?

Java中的序列化是一种将对象状态写入字节流的机制。它主要用于Hibernate, RMI, JPA, EJB和JMS技术。它主要用于在网络上传播对象的状态(称为封送处理)。可序列化的接口用于执行序列化。当你需要将程序状态保存到文件之类的存储时, 这将很有帮助。在稍后的时间, 可以使用反序列化还原此文件的内容。还需要实现RMI(远程方法调用)。借助RMI, 可以在一台计算机上调用另一台计算机上Java对象的方法。

Java序列化

更多细节。


200)如何使一个可在Java中序列化的类?

通过实现Serializable接口, 可以使一个类可序列化。


201)如果基类正在实现Serializable接口, 如何避免在子类中进行序列化?

如果基类旨在实现Serializable接口, 则阻止子类的序列化非常棘手。但是, 我们不能直接这样做, 但是可以通过在子类中实现writeObject()或readObject()方法并从这些方法中抛出NotSerializableException来避免序列化。考虑以下示例。

import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.NotSerializableException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
class Person implements Serializable 
{ 
    String name = " ";
    public Person(String name)  
    { 
        this.name = name; 
    }       
} 
class Employee extends Person
{ 
    float salary;
    public Employee(String name, float salary)  
    { 
        super(name); 
        this.salary = salary; 
    } 
    private void writeObject(ObjectOutputStream out) throws IOException 
    { 
        throw new NotSerializableException(); 
    } 
    private void readObject(ObjectInputStream in) throws IOException 
    { 
        throw new NotSerializableException(); 
    } 
      
} 
public class Test 
{ 
    public static void main(String[] args)  
            throws Exception  
    { 
        Employee emp = new Employee("Sharma", 10000); 
          
        System.out.println("name = " + emp.name); 
        System.out.println("salary = " + emp.salary); 
          
        FileOutputStream fos = new FileOutputStream("abc.ser"); 
        ObjectOutputStream oos = new ObjectOutputStream(fos); 
              
        oos.writeObject(emp); 
              
        oos.close(); 
        fos.close(); 
              
        System.out.println("Object has been serialized"); 
          
        FileInputStream f = new FileInputStream("ab.txt"); 
        ObjectInputStream o = new ObjectInputStream(f); 
              
        Employee emp1 = (Employee)o.readObject(); 
              
        o.close(); 
        f.close(); 
              
        System.out.println("Object has been deserialized"); 
          
        System.out.println("name = " + emp1.name); 
        System.out.println("salary = " + emp1.salary); 
    } 
}

202)可以通过网络传输序列化对象吗?

是的, 我们可以通过网络传输序列化的对象, 因为序列化的对象以字节形式存储在内存中, 并且可以通过网络传输。我们还可以将序列化的对象写入磁盘或数据库。


203)什么是反序列化?

反序列化是从序列化状态重建对象的过程。这是序列化的反向操作。 ObjectInputStream反序列化使用ObjectOutputStream编写的对象和原始数据。

import java.io.*;
class Depersist{
 public static void main(String args[])throws Exception{
  
  ObjectInputStream in=new ObjectInputStream(new FileInputStream("f.txt"));
  Student s=(Student)in.readObject();
  System.out.println(s.id+" "+s.name);

  in.close();
 }
}
211 ravi

204)什么是瞬时关键字?

如果将任何数据成员定义为瞬态, 则不会序列化。通过确定瞬态关键字, 变量的值在恢复时无需保留。更多细节。


205)什么是可外部化?

Externalizable接口用于以压缩格式将对象的状态写入字节流。它不是标记界面。


206)Serializable和Externalizable接口有什么区别?

No. Serializable Externalizable
Serializable接口没有任何方法, 即它是标记接口。 Externalizable接口包含的不是标记接口, 它包含两个方法, 即writeExternal()和readExternal()。
它用于”标记” Java类, 以便这些类的对象可以获得一定的功能。 Externalizable接口为编程人员提供了对序列化逻辑的控制。
它易于实现, 但具有较高的性能成本。 它用于执行序列化, 通常可以提高性能。
序列化中不会调用任何类构造函数。 使用此接口时, 我们必须调用公共默认构造函数。

.


网络面试问题


207)简要描述Java套接字编程?

Java套接字编程用于在不同JRE上运行的应用程序之间的通信。 Java套接字编程可以是面向连接的或无连接的。 Socket和ServerSocket类用于面向连接的套接字编程和DatagramSocket, 而DatagramPacket类用于无连接套接字编程。套接字编程中的客户端必须知道两个信息:

  • 服务器的IP地址
  • 端口号

208)什么是插座?

套接字只是机器之间通信的端点。它提供了使用TCP连接两台计算机的连接机制。 Socket类可用于创建套接字。


209)当两台计算机通过TCP连接时, 应遵循哪些步骤?

当两台计算机通过TCP连接时, 将执行以下步骤。

  • ServerSocket对象由服务器实例化, 该对象表示将建立连接的端口号。
  • 实例化ServerSocket对象后, 服务器将调用ServerSocket类的accept()方法, 使服务器等待, 直到客户端尝试在给定端口上连接到服务器。
  • 同时, 服务器正在等待, 客户端通过实例化Socket类来创建套接字。套接字类构造函数接受服务器端口号和服务器名称。
  • 套接字类构造函数尝试以指定的名称与服务器连接。如果建立连接, 则客户端将具有可以与服务器通信的套接字对象。
  • 服务器调用的accept()方法返回对与服务器连接的服务器上新套接字的引用。

210)用Java编写程序以建立客户端和服务器之间的连接?

考虑以下程序, 该程序在客户端和服务器之间建立连接。

文件:MyServer.java

import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args){
try{
ServerSocket ss=new ServerSocket(6666);
Socket s=ss.accept();//establishes connection 
DataInputStream dis=new DataInputStream(s.getInputStream());
String  str=(String)dis.readUTF();
System.out.println("message= "+str);
ss.close();
}catch(Exception e){System.out.println(e);}
}
}

文件:MyClient.java

import java.io.*;
import java.net.*;
public class MyClient {
public static void main(String[] args) {
try{  
Socket s=new Socket("localhost", 6666);
DataOutputStream dout=new DataOutputStream(s.getOutputStream());
dout.writeUTF("Hello Server");
dout.flush();
dout.close();
s.close();
}catch(Exception e){System.out.println(e);}
}
}

211)如何将192.18.97.39这样的数字IP地址转换为java.sun.com等主机名?

通过InetAddress.getByName(” 192.18.97.39″)。getHostName(), 其中192.18.97.39是IP地址。考虑以下示例。

import java.io.*;  
import java.net.*;  
public class InetDemo{  
public static void main(String[] args){  
try{  
InetAddress ip=InetAddress.getByName("195.201.10.8");  

System.out.println("Host Name: "+ip.getHostName());  
}catch(Exception e){System.out.println(e);}  
}  
}

反思面试问题


212)反射是什么?

反射是在运行时检查或修改类的运行时行为的过程。 java.lang.Class类提供了各种方法, 可用于获取元数据, 检查和更改类的运行时行为。 java.lang和java.lang.reflect包提供了Java反射的类。它用于:

  • IDE(集成开发环境), 例如Eclipse, MyEclipse, NetBeans。
  • 调试器
  • 测试工具等

213)使用java.lang.Class类的目的是什么?

java.lang.Class类主要执行两个任务:

  • 提供在运行时获取类的元数据的方法。
  • 提供检查和更改类的运行时行为的方法。

214)实例化Class类的方法是什么?

有三种方法可以实例化Class类。

Class类的forName()方法:forName()方法用于动态加载类。它返回Class类的实例。如果你知道类的全限定名, 则应使用它。这不能用于基本类型。

Object类的getClass()方法:返回Class类的实例。如果你知道类型, 则应使用它。而且, 它可以与原语一起使用。

.class语法:如果类型可用, 但是没有实例, 则可以通过在类型名称后附加” .class”来获得Class。它也可以用于原始数据类型。


215)以下Java程序的输出是什么?

class Simple{  
 public Simple()
 {
   System.out.println("Constructor of Simple class is invoked");
 }
 void message(){System.out.println("Hello Java");}  
}  
  
class Test1{  
 public static void main(String args[]){  
  try{  
  Class c=Class.forName("Simple");  
  Simple s=(Simple)c.newInstance();  
  s.message();  
  }catch(Exception e){System.out.println(e);}  
 }  
}

输出

Constructor of Simple class is invoked
Hello Java

解释

Class类的newInstance()方法用于在运行时调用构造函数。在此程序中, 将创建Simple类的实例。


216)使用javap的目的是什么?

javap命令反汇编一个类文件。 javap命令显示有关类文件中存在的字段, 构造函数和方法的信息。

语法

javap fully_class_name


217)你可以从类外部访问私有方法吗?

是的, 如果该类不受保护, 则可以通过更改类的运行时行为来实现。

更多细节。


其他面试问题


218)什么是包装器类?

包装器类是允许将基本类型作为对象访问的类。换句话说, 我们可以说包装器类是内置的Java类, 它允许将对象转换为基元, 并将基元转换为对象。将基元转换为对象的过程称为自动装箱, 而将对象转换为基元的过程称为拆箱。下面给出了java.lang包中存在的八个包装器类。

原始类型 包装类
Boolean
Character
Byte
Short
Integer
Long
Float
Double

219)什么是自动装箱和拆箱?什么时候发生?

自动装箱是将原始数据类型转换为相应包装器类对象(例如, 从int到Integer)的过程。拆箱是将包装器类对象转换为原始数据类型的过程。例如, 整数到int。取消装箱和自动装箱在Java中自动发生。但是, 我们可以使用诸如valueOf()或xxxValue()之类的方法从外部将其转换为另一种。

每当需要包装类对象并提供原始数据类型时, 都可能发生这种情况, 反之亦然。

  • 将基本类型添加到Collection中, 例如Java中的ArrayList。
  • 创建参数化类的实例, 例如ThreadLocal, 它们期望使用Type。
  • Java会在需要时自动将基元转换为对象, 而在方法调用中提供另一种。
  • 将原始类型分配给对象类型时。

220)下面的Java程序的输出是什么?

public class Test1
{
  public static void main(String[] args) {
  Integer i = new Integer(201);
  Integer j = new Integer(201);
  if(i == j)
  {
    System.out.println("hello");
  }
  else 
  {
    System.out.println("bye");
  }
  }
}

输出

bye

解释

Integer类缓存从-127到127的整数值。因此, 只能在-128到127的范围内创建Integer对象。运算符==不适用于大于127的值;因此, 再见被打印了。


221)什么是对象克隆?

对象克隆是一种创建对象的精确副本的方法。 Object类的clone()方法用于克隆对象。 java.lang.Cloneable接口必须由我们要创建其对象克隆的类实现。如果我们不实现Cloneable接口, 则clone()方法将生成CloneNotSupportedException。 clone()方法在Object类中定义。 clone()方法的语法如下:

受保护的对象clone()抛出CloneNotSupportedException


222)对象克隆的优缺点是什么?

对象克隆的优势

  • 你无需编写冗长和重复的代码。只需将抽象类与4或5行长clone()方法一起使用。
  • 这是复制对象的最简单, 最有效的方法, 尤其是当我们将其应用于已开发或旧项目时。只需定义一个父类, 在其中实现Cloneable, 提供clone()方法的定义即可完成任务。
  • Clone()是复制数组的最快方法。

对象克隆的缺点

  • 要使用Object.clone()方法, 我们必须更改代码的许多语法, 例如实现Cloneable接口, 定义clone()方法和处理CloneNotSupportedException, 最后调用Object.clone()等。
  • 当其中没有任何方法时, 我们必须实现Cloneable接口。我们必须使用它来告诉JVM我们可以对对象执行clone()。
  • Object.clone()受保护, 因此我们必须提供自己的clone()并从中间接调用Object.clone()。
  • Object.clone()不调用任何构造函数, 因此我们对对象构造没有任何控制。
  • 如果要在子类中编写一个clone方法, 则其所有超类都应在其中定义clone()方法或从另一个父类继承该方法。否则, super.clone()链将失败。
  • Object.clone()仅支持浅表复制, 但是如果需要深度克隆, 则需要覆盖它。

223)什么是本机方法?

本机方法是以Java以外的语言实现的方法。本地方法有时也称为外来方法。


224)strictfp关键字的目的是什么?

Java strictfp关键字可确保如果在浮点变量中执行操作, 你将在每个平台上获得相同的结果。精度因平台而异, 这就是Java编程语言提供了strictfp关键字的原因, 以便你在每个平台上都能获得相同的结果。因此, 现在你可以更好地控制浮点算法了。


225)System类的目的是什么?

System类的目的是提供对系统资源(例如标准输入和输出)的访问。无法实例化。系统类提供的功能如下。

  • 标准输入
  • 错误输出流
  • 标准输出
  • 复制数组部分的实用方法
  • 加载文件和库的实用程序

Java System类有三个字段, 即静态打印流err, 静态输入流和标准输出流。


226)当有人提到Java中的浅表副本时, 会想到什么?

对象克隆。


227)什么是单例课程?

单例类是不能多次实例化的类。要使类成为单例, 我们可以将其构造函数设为私有, 或使用静态的getInstance方法。考虑以下示例。

class Singleton{
    private static Singleton single_instance = null;
    int i;
     private Singleton ()
     {
         i=90;
     }
     public static Singleton getInstance()
     {
         if(single_instance == null)
         {
             single_instance = new Singleton();
         }
         return single_instance;
     }
}
public class Main 
{
    public static void main (String args[])
    {
        Singleton first = Singleton.getInstance();
        System.out.println("First instance integer value:"+first.i);
        first.i=first.i+90;
        Singleton second = Singleton.getInstance();
        System.out.println("Second instance integer value:"+second.i);
    }
}

228)编写一个Java程序, 打印出在命令行中给定的所有值。

程序

class A{
public static void main(String args[]){

for(int i=0;i<args.length;i++)
System.out.println(args[i]);

}
}
compile by > javac A.java
run by > java A sonoo jaiswal 1 3 abc

输出

sonoo
jaiswal
1
3
abc

229)哪些容器使用边框布局作为其默认布局?

Window, Frame和Dialog类使用边框布局作为其默认布局。


230)哪些容器将FlowLayout用作默认布局?

Panel和Applet类使用FlowLayout作为其默认布局。


231)什么是无与伦比的组件?

Swing的轻量级组件称为无与伦比的组件。 Spring具有其库, 因此它不使用来自操作系统的资源, 因此具有轻量级的组件。


232)滚动条和ScrollPane有什么区别吗?

滚动条是一个组件, 而ScrollPane是一个容器。 ScrollPane处理其事件并执行其滚动。


233)什么是轻量级组件?

轻量级组件是不与本地调用一起获得图形单元的组件。他们共享其父组件图形单元来呈现它们。例如, Swing组件和JavaFX组件。


234)什么是重量级组件?

操作系统提供的便携式元素称为重量级组件。 AWT限于操作系统提供的图形类, 因此, 它仅实现所有平台支持的最小屏幕元素子集。依赖于操作系统的UI发现工具称为重量级组件。


235)什么是小程序?

小应用程序是在浏览器中运行并生成动态内容的小型Java程序。它嵌入在网页中, 并在客户端运行。它是安全的, 响应时间较短。它可以由在许多平台(包括Linux, Windows, Mac Os等)下运行的浏览器执行。但是, 客户端浏览器需要插件才能执行小程序。下图显示了Applet的体系结构。

小程序的等级

创建小程序时, 将依次调用以下方法。

  • 在里面()
  • 开始()
  • 涂料()

当applet被销毁时, 以下功能将依次调用。

  • 停()
  • 破坏()

236)你可以编写一个既可以用作小程序又可以用作应用程序的Java类吗?

是。将main()方法添加到小程序。


国际化面试题


237)什么是语言环境?

语言环境对象代表特定的地理, 政治或文化区域。此对象可用于获取特定于语言环境的信息, 例如国家/地区名称, 语言, 变体等。

import java.util.*;
public class LocaleExample {
public static void main(String[] args) {
Locale locale=Locale.getDefault();
//Locale locale=new Locale("fr", "fr");//for the specific locale

System.out.println(locale.getDisplayCountry());
System.out.println(locale.getDisplayLanguage());
System.out.println(locale.getDisplayName());
System.out.println(locale.getISO3Country());
System.out.println(locale.getISO3Language());
System.out.println(locale.getLanguage());
System.out.println(locale.getCountry());
	
}
}

输出

United States
English
English (United States)
USA
eng
en
US

238)你将如何加载特定的语言环境?

通过ResourceBundle.getBundle(?)方法。


Java Bean面试问题


239)什么是JavaBean?

JavaBean是用Java编程语言编写的可重用软件组件, 旨在由软件开发环境(如JBuilder或VisualAge for Java)以可视方式进行操作。 t。 JavaBean将许多对象封装到一个对象中, 以便我们可以从多个位置访问该对象。而且, 它提供了容易的维护。考虑下面的示例来创建JavaBean类。

//Employee.java
package mypack;
public class Employee implements java.io.Serializable{
private int id;
private String name;
public Employee(){}
public void setId(int id){this.id=id;}
public int getId(){return id;}
public void setName(String name){this.name=name;}
public String getName(){return name;}
}

240)使用Java bean的目的是什么?

根据Java白皮书, 它是可重用的软件组件。 Bean将许多对象封装为一个对象, 因此我们可以从多个位置访问该对象。而且, 它提供了容易的维护。


241)你对bean的持久属性有什么了解?

当属性, 字段和状态信息保存到存储中或从存储中检索时, Java bean的持久性属性就起作用了。


RMI面试问题


242)什么是RMI?

RMI(远程方法调用)是一种API, 提供了一种使用Java创建分布式应用程序的机制。 RMI允许对象调用在另一个JVM中运行的对象上的方法。 RMI使用两个对象存根和框架在应用程序之间提供远程通信。


243)存根和骨架的目的是什么?

存根

存根是一个对象, 充当客户端的网关。所有传出的请求都通过它路由。它位于客户端, 代表远程对象。当调用方调用存根对象上的方法时, 它将执行以下任务:

  • 它启动与远程虚拟机(JVM)的连接。
  • 它将参数写入并传输(封送)到远程虚拟机(JVM)。
  • 它等待结果。
  • 它读取(解组)返回值或异常。
  • 最后, 它将值返回给调用方。

骨架

骨架是一个对象, 充当服务器端对象的网关。所有传入的请求都通过它路由。当框架接收到传入的请求时, 它将执行以下任务:

  • 它读取远程方法的参数。
  • 它在实际的远程对象上调用该方法。
  • 它写入结果并将其传输(封送)给调用方。

244)编写基于RMI的程序涉及哪些步骤?

编写基于RMI的程序需要执行6个步骤。

  • 创建远程接口。
  • 提供远程接口的实现。
  • 编译实现类, 并使用rmic工具创建存根和骨架对象。
  • 通过rmiregistry工具启动注册表服务。
  • 创建并启动远程应用程序。
  • 创建并启动客户端应用程序。

245)RMI中HTTP隧道的用途是什么?

HTTP隧道可以定义为不需要任何设置即可在防火墙环境中工作的方法。它通过代理服务器处理HTTP连接。但是, 它不允许出站TCP连接。


246)什么是JRMP?

JRMP(Java远程方法协议)可以定义为特定于Java的, 基于流的协议, 该协议查找并引用远程对象。它要求客户端和服务器都使用Java对象。它是线级协议, 在RMI下和TCP / IP上运行。


247)基于RMI和CORBA的应用程序可以交互吗?

是的他们可以。 IIOP提供RMI而不是JRMP作为传输协议。


Java核心:数据结构面试问题


248)如何在Java中执行冒泡排序?

考虑以下程序, 以在Java中执行冒泡排序。

public class BubbleSort {
  public static void main(String[] args) {
  int[] a = {10, 9, 7, 101, 23, 44, 12, 78, 34, 23};
  for(int i=0;i<10;i++)
  {
    for (int j=0;j<10;j++)
    {
      if(a[i]<a[j])
      {
        int temp = a[i];
        a[i]=a[j];
        a[j] = temp; 
      }
    }
  }
  System.out.println("Printing Sorted List ...");
  for(int i=0;i<10;i++)
  {
    System.out.println(a[i]);
  }
}
}

输出

Printing Sorted List . . . 
7
9
10
12
23
34
34
44
78 
101

249)如何在Java中执行二进制搜索?

考虑以下程序, 以使用Java执行二进制搜索。

import java.util.*;
public class BinarySearch {
public static void main(String[] args) {
  int[] arr = {16, 19, 20, 23, 45, 56, 78, 90, 96, 100};
  int item, location = -1;
  System.out.println("Enter the item which you want to search");
  Scanner sc = new Scanner(System.in);
  item = sc.nextInt();
  location = binarySearch(arr, 0, 9, item);
  if(location != -1)
  System.out.println("the location of the item is "+location);
  else 
    System.out.println("Item not found");
  }
public static int binarySearch(int[] a, int beg, int end, int item)
{
  int mid;
  if(end >= beg) 
  { 
    mid = (beg + end)/2;
    if(a[mid] == item)
    {
      return mid+1;
    }
    else if(a[mid] < item) 
    {
      return binarySearch(a, mid+1, end, item);
    }
    else 
    {
      return binarySearch(a, beg, mid-1, item);
    }
  }
  return -1; 
}
}

输出

Enter the item which you want to search 
45 
the location of the item is 5

250)如何在Java中执行选择排序?

考虑以下程序, 以在Java中执行选择排序。

public class SelectionSort {
public static void main(String[] args) {
  int[] a = {10, 9, 7, 101, 23, 44, 12, 78, 34, 23};
  int i, j, k, pos, temp;
  for(i=0;i<10;i++)
  {
    pos = smallest(a, 10, i);
    temp = a[i];
    a[i]=a[pos];
    a[pos] = temp;
  }
  System.out.println("\nprinting sorted elements...\n");
  for(i=0;i<10;i++)
  {
    System.out.println(a[i]);
  }
}
public static int smallest(int a[], int n, int i)
{
  int small, pos, j;
  small = a[i];
  pos = i;
  for(j=i+1;j<10;j++)
  {
    if(a[j]<small)
    {
      small = a[j];
      pos=j;
    }
  }
  return pos;
}
}

输出

printing sorted elements...
7
9
10
12
23
23
34
44
78
101

251)如何在Java中执行线性搜索?

考虑以下程序, 以在Java中执行线性搜索。

import java.util.Scanner;

public class Leniear_Search {
public static void main(String[] args) {
  int[] arr = {10, 23, 15, 8, 4, 3, 25, 30, 34, 2, 19};
  int item, flag=0; 
  Scanner sc = new Scanner(System.in);
  System.out.println("Enter Item ?");
  item = sc.nextInt();
  for(int i = 0; i<10; i++)
  {
    if(arr[i]==item)
    {
      flag = i+1;
      break;
    }
    else 
      flag = 0; 
  }
  if(flag != 0)
  {
    System.out.println("Item found at location" + flag);
  }
  else 
    System.out.println("Item not found");
  
}
}

输出

Enter Item ?
23
Item found at location 2
Enter Item ?
22
Item not found

252)如何在Java中执行合并排序?

考虑以下程序以Java进行合并排序。

public class MyMergeSort
{
void merge(int arr[], int beg, int mid, int end)
{

int l = mid - beg + 1;
int r = end - mid;

intLeftArray[] = new int [l];
intRightArray[] = new int [r];

for (int i=0; i<l; ++i)
LeftArray[i] = arr[beg + i];

for (int j=0; j<r; ++j)
RightArray[j] = arr[mid + 1+ j];


int i = 0, j = 0;
int k = beg;
while (i<l&&j<r)
{
if (LeftArray[i] <= RightArray[j])
{
arr[k] = LeftArray[i];
i++;
}
else
{
arr[k] = RightArray[j];
j++;
}
k++;
}
while (i<l)
{
arr[k] = LeftArray[i];
i++;
k++;
}

while (j<r)
{
arr[k] = RightArray[j];
j++;
k++;
}
}

void sort(int arr[], int beg, int end)
{
if (beg<end)
{
int mid = (beg+end)/2;
sort(arr, beg, mid);
sort(arr , mid+1, end);
merge(arr, beg, mid, end);
}
}
public static void main(String args[])
{
intarr[] = {90, 23, 101, 45, 65, 23, 67, 89, 34, 23};
MyMergeSort ob = new MyMergeSort();
ob.sort(arr, 0, arr.length-1);

System.out.println("\nSorted array");
for(int i =0; i<arr.length;i++)
{
  System.out.println(arr[i]+"");
}
}
}

输出

Sorted array 
23
23
23
34
45
65
67
89
90
101

253)如何在Java中执行快速排序?

考虑以下程序, 以用Java执行快速排序。

public class QuickSort {
public static void main(String[] args) {
    int i;
    int[] arr={90, 23, 101, 45, 65, 23, 67, 89, 34, 23};
    quickSort(arr, 0, 9);
    System.out.println("\n The sorted array is: \n");
    for(i=0;i<10;i++)
    System.out.println(arr[i]);
  }
  public static int partition(int a[], int beg, int end)
  {
    
    int left, right, temp, loc, flag; 
    loc = left = beg;
    right = end;
    flag = 0;
    while(flag != 1)
    {
      while((a[loc] <= a[right]) && (loc!=right))
      right--;
      if(loc==right)
      flag =1;
      elseif(a[loc]>a[right])
      {
        temp = a[loc];
        a[loc] = a[right];
        a[right] = temp;
        loc = right;
      }
      if(flag!=1)
      {
        while((a[loc] >= a[left]) && (loc!=left))
        left++;
        if(loc==left)
        flag =1;
        elseif(a[loc] <a[left])
        {
          temp = a[loc];
          a[loc] = a[left];
          a[left] = temp;
          loc = left;
        }
      }
    }
    returnloc;
  }
  static void quickSort(int a[], int beg, int end)
  {
    
    int loc;
    if(beg<end)
    {
      loc = partition(a, beg, end);
      quickSort(a, beg, loc-1);
      quickSort(a, loc+1, end);
    }
  }
}

输出

The sorted array is: 
23
23
23
34
45
65
67
89
90
101

254)用Java编写程序来创建一个包含n个节点的双向链表。

考虑以下程序来创建一个包含n个节点的双向链表。

public class CountList {
    
    //Represent a node of the doubly linked list

    class Node{
        int data;
        Node previous;
        Node next;
        
        public Node(int data) {
            this.data = data;
        }
    }
    
    //Represent the head and tail of the doubly linked list
    Node head, tail = null;
    
    //addNode() will add a node to the list
    public void addNode(int data) {
        //Create a new node
        Node newNode = new Node(data);
        
        //If list is empty
        if(head == null) {
            //Both head and tail will point to newNode
            head = tail = newNode;
            //head's previous will point to null
            head.previous = null;
            //tail's next will point to null, as it is the last node of the list
            tail.next = null;
        }
        else {
            //newNode will be added after tail such that tail's next will point to newNode
            tail.next = newNode;
            //newNode's previous will point to tail
            newNode.previous = tail;
            //newNode will become new tail
            tail = newNode;
            //As it is last node, tail's next will point to null
            tail.next = null;
        }
    }
    
    //countNodes() will count the nodes present in the list
    public int countNodes() {
        int counter = 0;
        //Node current will point to head
        Node current = head;
        
        while(current != null) {
            //Increment the counter by 1 for each node
            counter++;
            current = current.next;
        }
        return counter;
    }
    
    //display() will print out the elements of the list
    public void display() {
        //Node current will point to head
        Node current = head;
        if(head == null) {
            System.out.println("List is empty");
            return;
        }
        System.out.println("Nodes of doubly linked list: ");
        while(current != null) {
            //Prints each node by incrementing the pointer.

            System.out.print(current.data + " ");
            current = current.next;
        }
    }
    
    public static void main(String[] args) {
        
        CountList dList = new CountList();
        //Add nodes to the list
        dList.addNode(1);
        dList.addNode(2);
        dList.addNode(3);
        dList.addNode(4);
        dList.addNode(5);
        
        //Displays the nodes present in the list
        dList.display();
        
        //Counts the nodes present in the given list
        System.out.println("\nCount of nodes present in the list: " + dList.countNodes());
    }
}

输出

Nodes of doubly linked list: 
1 2 3 4 5 
Count of nodes present in the list: 5

255)用Java编写程序, 以从循环链表中找到最大值和最小值节点。

考虑下面的程序。

public class MinMax {
    //Represents the node of list.
    public class Node{
        int data;
        Node next;
        public Node(int data) {
            this.data = data;
        }
    }
    
    //Declaring head and tail pointer as null.
    public Node head = null;
    public Node tail = null;
    
    //This function will add the new node at the end of the list.
    public void add(int data){
        //Create new node
        Node newNode = new Node(data);
        //Checks if the list is empty.
        if(head == null) {
             //If list is empty, both head and tail would point to new node.
            head = newNode;
            tail = newNode;
            newNode.next = head;
        }
        else {
            //tail will point to new node.
            tail.next = newNode;
            //New node will become new tail.
            tail = newNode;
            //Since, it is circular linked list tail will points to head.
            tail.next = head;
        }
    }
    
    //Finds out the minimum value node in the list
    public void minNode() {
        Node current = head;
        //Initializing min to initial node data
        int min = head.data;
        if(head == null) {
            System.out.println("List is empty");
        }
        else {
             do{
                 //If current node's data is smaller than min
                 //Then replace value of min with current node's data
                 if(min > current.data) {
                     min = current.data;
                 }
                 current= current.next;
            }while(current != head);
        
            System.out.println("Minimum value node in the list: "+ min);
        }
    }
        
    //Finds out the maximum value node in the list
    public void maxNode() {
        Node current = head;
        //Initializing max to initial node data
        int max = head.data;
        if(head == null) {
            System.out.println("List is empty");
        }
        else {
             do{
                 //If current node's data is greater than max
                 //Then replace value of max with current node's data
                 if(max < current.data) {
                     max = current.data;
                 }
                 current= current.next;
                }while(current != head);
             
            System.out.println("Maximum value node in the list: "+ max);
        }
    }
                
    public static void main(String[] args) {
        MinMax cl = new MinMax();
        //Adds data to the list
        cl.add(5);
        cl.add(20);
        cl.add(10);
        cl.add(1);
        //Prints the minimum value node in the list
        cl.minNode();
        //Prints the maximum value node in the list
        cl.maxNode();
    }
}

输出

Minimum value node in the list: 1
Maximum value node in the list: 20

256)用Java编写一个程序来计算二叉树的奇数级和偶数级节点之和之间的差。

考虑下面的程序。

import java.util.LinkedList;
import java.util.Queue;
 
public class DiffOddEven {
    
    //Represent a node of binary tree
    public static class Node{
        int data;
        Node left;
        Node right;
        
        public Node(int data){
            //Assign data to the new node, set left and right children to null
            this.data = data;
            this.left = null;
            this.right = null;
            }
        }
    
    //Represent the root of binary tree
    public Node root;
  
    public DiffOddEven(){
        root = null;
    }
 
    //difference() will calculate the difference between sum of odd and even levels of binary tree
    public int difference() {
          int oddLevel = 0, evenLevel = 0, diffOddEven = 0;
          
          //Variable nodesInLevel keep tracks of number of nodes in each level
          int nodesInLevel = 0;
          
          //Variable currentLevel keep track of level in binary tree
          int currentLevel = 0;
          
          //Queue will be used to keep track of nodes of tree level-wise
          Queue<Node> queue = new LinkedList<Node>();
          
          //Check if root is null
          if(root == null) {
              System.out.println("Tree is empty");
              return 0;
          }
          else {
              //Add root node to queue as it represents the first level
              queue.add(root);
              currentLevel++;
              
              while(queue.size() != 0) {
                  
                  //Variable nodesInLevel will hold the size of queue i.e. number of elements in queue
                  nodesInLevel = queue.size();
                  
                  while(nodesInLevel > 0) {
                      Node current = queue.remove();
                      
                    //Checks if currentLevel is even or not.
                      if(currentLevel % 2 == 0)
                          //If level is even, add nodes's to variable evenLevel
                          evenLevel += current.data;
                      else
                          //If level is odd, add nodes's to variable oddLevel
                          oddLevel += current.data;
                      
                      //Adds left child to queue
                      if(current.left != null)
                          queue.add(current.left);
                      //Adds right child to queue
                      if(current.right != null) 
                          queue.add(current.right);
                     nodesInLevel--;
                  }
                  currentLevel++;
              }
              //Calculates difference between oddLevel and evenLevel
              diffOddEven = Math.abs(oddLevel - evenLevel);
          }
          return diffOddEven;
      }
  
    public static void main (String[] args) {
        
        DiffOddEven bt = new DiffOddEven();
        //Add nodes to the binary tree
        bt.root = new Node(1);
        bt.root.left = new Node(2);
        bt.root.right = new Node(3);
        bt.root.left.left = new Node(4);
        bt.root.right.left = new Node(5);
        bt.root.right.right = new Node(6);
    
        //Display the difference between sum of odd level and even level nodes
        System.out.println("Difference between sum of odd level and even level nodes: " + bt.difference());
}
}

输出

Difference between sum of odd level and even level nodes: 11


1 2 3 4 5


Java OOP面试问题
Java字符串和异常面试问题
JDBC面试问题
JSP面试问题
休眠面试问题
SQL面试题
Android面试题
MySQL面试问题

1

2

3

4

5

抽象类可以具有方法主体(非抽象方法)。

抽象类可以具有实例变量。

抽象类可以具有构造函数。

抽象类可以具有静态方法。

你可以扩展一个抽象类。

抽象类可以提供接口的实现。

abstract关键字用于声明抽象类。

抽象类可以扩展另一个Java类并实现多个Java接口。

可以使用关键字extends扩展抽象类

Java抽象类可以具有类成员, 例如private, protected等。

例:

公共抽象类Shape {

公共抽象无效draw();

}

1)throw关键字用于显式引发异常。

2)检查的异常不能仅通过throw传播。

3)throw关键字后跟一个实例。

4)在方法中使用throw关键字。

5)你不能抛出多个异常。

1)

2)

3)

1)

2)

会员内部舱位

匿名内部阶层

本地内部人士

1)

2)

1)

2)

3)

4)

boolean

char

字节

short

int

long

float

Java基础面试问题

Java多线程面试问题

Java Collection面试题

Servlet面试问题

春季面试问题

PL / SQL面试问题

Oracle面试问题

SQL Server面试问题

赞(0) 打赏
未经允许不得转载:srcmini » 300个核心Java面试问题和答案(二)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

微信扫一扫打赏