Javaのインタビューの質問を学んで

図1に示すように、メモリ・スタック(スタック)の説明のヒープ(ヒープ)領域及び方法(メソッド領域)の使用。
回答:通常、私たちはそこにあるオンサイトでの関数呼び出しの保存がJVMにおけるスタック領域を使用し、変数の基本データ型、オブジェクトへの参照を定義し、ヒープ上のスペースの新しいキーワードとコンストラクタによって作成されたオブジェクト、ヒープがありますガベージコレクタ管理の主要領域、今、ガベージコレクタは、世代コレクションアルゴリズムを使用していることを、スタック領域も旧世代と新世代に細分することができる、それは、終身特定エデン、サバイバーに分けることができます(とサバイバーへサバイバーからに分けることができます)。方法およびヒープ領域は、個々のスレッドは、JVMにロードされたクラス情報を格納するためのメモリ領域を共有している、定数、静的変数、コード及び他のデータをコンパイルするJITコンパイラ等の直接描画などのリテラル(リテラル)プログラム100、「こんにちは」と定数は、定数プールにあるから、プール方法の定常領域の一部です。スタック領域が不足し、最速が、スタックは通常、多数のオブジェクトをヒープ領域にあり、スタックとヒープサイズはJVM起動パラメータによって調整することができ、非常に小さいを動作させるためのスタック領域は、ヒープながら、にStackOverflowErrorにつながるとプールスペースの一定の欠如はOutOfMemoryErrorが発生するでしょう。

String str = new String("hello");

スタック上に上記のステートメントのstr変数は、リテラルの方法は、エリアにある新しい文字列ヒープ上のオブジェクト、および「ハロー」とそれを作成します。

2、配列には長さ()メソッドを持っていますか?文字列には長さ()メソッドを持っていませんか?
回答:いいえ配列の長さ()メソッドは、長さ属性ありません。文字列は、長さ()メソッドを有します。
JavaScriptのは、文字列の長さを容易に混乱やJava長さプロパティにより得られました。

(上書き)場合は3、コンストラクタ(コンストラクタ)は書き換えることができますか?
A:コンストラクタは継承できませんので、書き換えることはできませんが、過負荷状態にすることができます。

図4に示すように、両者は同じ値(x.equals(Y)== true)をオブジェクト 、 それは、この文の権利を異なるハッシュコードを有することができますか?
A:いいえ、2つのオブジェクトが、XおよびYが満たす場合x.equals(Y)= TRUE、ハッシュコード、その(ハッシュコード)が同じでなければなりません。
:eqaulsとhashCodeメソッドが指定されているのJava
(1)は、2つの同一の物体(戻り真equalsメソッド)場合、それらは同一のハッシュコード値でなければならない;
(2)2つのオブジェクトが同じハッシュコードを持っている場合、そうでありません必ずしも同じ。
もちろん、あなたそれに従うことができますが、上記の原則に違反した場合は、コンテナを使用した場合、新たな要素の効率を向上させながら、同じオブジェクトは、コレクションセットに表示できることがわかりますたくないかもしれませんが大幅にハッシュストレージを使用するように(削減されますシステム、頻繁な衝突のハッシュコードは、アクセス性能の急激な低下をもたらす場合)。

5、Stringクラスを継承することができますか?
A:Stringクラスは、最終的なクラスが継承することはできませんです。

オブジェクトは、メソッドにパラメータとして渡されたとき6、この方法は、次いで、最終的にここで参照または値を転送することによって渡され、このオブジェクトのプロパティを変更し、変化の結果を返すことができますか?
A:値が渡されます。Java言語のメソッド呼び出しにのみ渡されたパラメータの値をサポートしています方法は、パラメータとしてオブジェクトインスタンスに渡されると、パラメータの値は、オブジェクトへの参照です。オブジェクトのプロパティは、呼び出されたプロシージャで変更できますが、変更は、発信者が参照するオブジェクトには影響しません。C ++やC#を送信してもよく、または参照によるパラメータの値が渡されたパラメータを変更します。あなたは、以下に示すC#コードで書かれていてもよいが、Javaで行うことはできません。

7、文字列とStringBuilderの、StringBufferの違いは?
A:文字列とStringBufferの/ StringBuilderを、保存して文字列を操作することができます:Javaプラットフォームは、文字列の2種類が用意されています。文字列の読み取り専用の文字列、文字列の文字列の参考文献の内容を変更することはできませんを意味します。文字列オブジェクトのStringBuffer / StringBuilderクラス表現を直接変更してもよいです。StringBufferオブジェクトは、あなたがスレッドを保証することができますので、synchronizedキーワードで多くの方法で文字列バッファ、StringBufferの中で複数のスレッドを使用する場合のStringBufferは、スレッドセーフである一方、セキュリティスレッドでは、StringBuilderのは、スレッドセーフではありません安全ですが、StringBuilderのアプローチはキーではない、それは間違った操作が発生した何かがあるかもしれません、スレッドセーフを保証することはできません。あなたはマルチスレッドで動作したいのであれば、我々はStringBufferのを使用する必要がありますが、シングルスレッドの場合には、速いのStringBuilderを使用することをお勧めします。

文字:文字列操作の小さな数に適用される
のStringBuilder:シングルスレッド文字バッファ内のケースの多数を動作させるのに適し
たStringBuffer:文字バッファ下の適切なマルチスレッドオペレーティング多数の行為を

図8に示すように、オーバーロード(過負荷)と書き換え可能(上書き)との差です。オーバーロードメソッドは、戻り値の種類に応じて区別することができますか?
:それは多型が、実行時に達成されるコンパイル時の多型を、実装されていることを除いて過負荷と書き換え==方法は、マルチステート方法です。==過負荷がクラスで発生し、同じ名前のメソッドがオーバーロードされたと考えられるパラメータの異なるリスト(異なるタイプ及び異なるパラメータの数または両方のパラメータ)である場合、リライトは、子と親クラスを発生しますサブクラスが要件を上書きルームで(親クラスでオーバーライドされたメソッドは、複数の例外よりもオーバーライドされた親クラスのメソッド宣言することはできませんが、この方法は、親よりも良いアクセスを無効にされ、同じ戻り値の型とオーバーライドされたメソッドでありますsの置換原則)。戻り値の型のための特別な要件をオーバーロードされません。

フェイスの質問は:Huawei社のフェースの質問は、このような質問をしている- 「できないのはなぜ区別オーバーロードされた戻り値の型に基づいて、」あなたに答えを伝えるために迅速!
戻り値の型のための特別な要件をオーバーロードしません

9、原則メカニズムJVMクラスのドキュメントの読み込みを説明しますか?
A:JVMは、Javaクラスローダーに、達成するクラスローダ(クラスローダー)とそのサブクラスによってクラスにロードされ、実行時に発見し、ロードクラスの原因であるJavaランタイム・システムの重要な構成要素でありますファイルクラス。
ジャワのクロスプラットフォームな性質として、コンパイルされたJavaソースコードが実行可能プログラムではなく、一つ以上のクラスファイル。プログラムは、Javaクラスを使用する必要がある場合、JVMは、クラスがロードされていることを接続(検証、準備および分析)と初期化を確実にします。ローディングは、データのクラスは、通常、バイトの配列を作成し、メモリ内の.classファイルの種類で読み出さ.classファイルに読み込むを参照し、クラスがロードされ、対応するオブジェクトのクラスを生成します。ロードされた後は、Classオブジェクトはので、この場合にはクラスがまだ利用できない、完全なものではありません。クラスが接続フェーズにロードされた後とき、検証、製造(メモリ静的変数として割り当てられ、デフォルトの初期値を設定)し、解析を含む、この相は、3つのステップ(直接参照へのシンボリック参照を置き換えます)。最後に、JVMのクラスがあって、初期化されます:1)が直接の親クラスであり、クラスが初期化されていない場合は、親クラスを初期化する; 2)クラス初期設定ステートメントがある場合は、順次これらの初期設定ステートメント上で実行されています。
ローダルート(ブートストラップ)、拡張ローダ(拡張)、システムローダ(システム)およびユーザ定義のクラスローダ(java.lang.ClassLoaderので:クラスローダによってクラスをロードするクラスローダを含む完了するサブクラス)。Java 2(JDK 1.2)を出発して、クラスローディングプロセスは、父親委託機構(PDM)を採用しました。PDMは、より優れたJavaプラットフォームの安全性を保証する、このメカニズムでは、JVMは、ルートブートストラップローダで、他のローダは、唯一の親クラスローダを持っています。最初のクラスをロードする親クラスローダがロード要求、親クラスローダときに無力セルフローディングローダーサブクラス。ブートストラップJVMは、Javaプログラムへの参照を提供していません。以下は、いくつかのクラスローダの説明です:

ブートストラップ:一般的にネイティブコードを使用して実装、ロードJVMの基本的なコアライブラリ(rt.jarの)責任がある;
拡張子:親がブートストラップにロードされ、ディレクトリを指定した属性図書館システムのjava.ext.dirsをロードし、
システム:既知のクラスローダのアプリケーション、親クラスの拡張。これは、最も広く使用されているクラスローダです。環境変数またはシステム属性のクラスパスには、ディレクトリのjava.class.pathを説明したクラス、ユーザ定義のデフォルトの親のローダーローダーを指定しました。

10、char型の変数には、中国語の文字を格納し、なぜことができますか?
:char型はUnicodeを使用してJavaでコーディングするので(ただ統一唯一の方法である文字セットの文字番号を使用し、任意の特定のエンコーディングを選択していない)、中国語の文字を格納することができ、char型は二つの単語を占め、セクション(16ビット)ので、中国は問題ありません置きます。

添加:外部JVMの内部の文字とは異なる症状を有することをUnicodeの手段を使用して、JVMの内部に文字が変換が必要とされるコード(例えば、ファイルシステムに格納されている)外部JVM内部から転送されたUnicodeです。したがって、Javaバイトストリームと文字ストリームがあり、そのようなInputStreamReaderの文字やバイトストリーム間OutputStreamReaderストリームを変換するストリーム変換器は、これら2つのクラスがアダプタクラスと文字列との間のバイトストリームである、と仮定コード変換タスク; Cプログラマはこれを達成するためには、おそらく達成するためのトランスコーディング組合(ユニオン/組合)機能、共有メモリに依存します。

11、抽象クラス(抽象クラス)とインタフェース(インタフェース)類似点と相違点は何ですか?
回答:いいえ抽象クラスとインタフェースをインスタンス化することはできないが、参照は、抽象クラスとインタフェースのタイプを定義することができます。それらのすべてを達成するための抽象メソッドへのクラスは抽象クラスまたは実装を継承する場合は、インタフェースの必要性、それ以外のクラスはまだ抽象クラスとして宣言する必要があります。抽象クラス以上の抽象インタフェースは、抽象メソッド、特定のメソッドを有することができる抽象クラスコンストラクタとして定義することができるが、コンストラクタメソッドは、すべての抽象メソッドである請求インタフェースを定義することができず。抽象クラスのメンバーは、プライベート、デフォルト、保護、公共することができ、およびインタフェースは、すべての公共のメンバーです。あなたは抽象クラスのメンバ変数を定義することができ、およびインタフェースで定義されたメンバ変数は、実際には定数です。クラスの抽象メソッドがありますが、抽象クラスは、抽象メソッドを持っていない可能性があり、抽象クラスとして宣言する必要があります。

12、静的な入れ子になったクラス(静的入れ子のクラス)と内部クラス(インナークラス)違いますか?
A:静的な入れ子のクラスは、それがインスタンス化された外部クラスのインスタンスに依存することはできません、静的(スタティック)内部クラスを宣言しています。通常、インスタンス化クラスに必要な内部クラスは外部でインスタンス化されます

インタビューの質問 - 次のコードはコンパイルエラーが生成されますどのような場所?

class Outer {
    class Inner {}
    public static void foo() { new Inner(); }
    public void bar() { new Inner(); }
    public static void main(String[] args) {
        new Inner();
    }
}

注:その外部のオブジェクトに依存するオブジェクトのJavaの中央アフリカの静的内部クラス、fooの中上面質問を作成し、主な方法は、静的メソッドで、静的メソッドなしこの、ないことは、いわゆる外部オブジェクトであるため、することはできませんあなたは、静的メソッドで内部クラスのオブジェクトを作成する場合は、内部クラスのオブジェクトを作成し、あなたがこれを行うことができます:

    new Outer().new Inner();

13は、Javaはそれは、シンプルに記述してくださいメモリリークになります。
A:Javaのガベージコレクション(GC)が理論的に存在している何のメモリリークは存在しませんので(も広くJavaで使用されているサーバー側のプログラミングの重要な原因である);しかし、実際の開発では、役に立たないが、到達可能があるかもしれませんGCを回復することはできませんので、メモリリークにつながるオブジェクト。一貫性のある状態に属するオブジェクトのセッションの休止例(キャッシュ)ガベージコレクタは、これらのオブジェクトを回復しないであろう、しかし、(閉じる)を閉じたり(フラッシュ)が空でない場合、ガベージは、無駄なこれらのオブジェクトをオブジェクトが存在してもよいですキャッシュは、メモリリークにつながる可能性があります。例えば次のコードは、メモリリークをもたらします。

import java.util.Arrays;
import java.util.EmptyStackException;

public class MyStack<T> {
    private T[] elements;
    private int size = 0;

    private static final int INIT_CAPACITY = 16;

    public MyStack() {
        elements = (T[]) new Object[INIT_CAPACITY];
    }

    public void push(T elem) {
        ensureCapacity();
        elements[size++] = elem;
    }

    public T pop() {
        if(size == 0) 
            throw new EmptyStackException();
        return elements[--size];
    }

    private void ensureCapacity() {
        if(elements.length == size) {
            elements = Arrays.copyOf(elements, 2 * size + 1);
        }
    }
}

一目見ただけで任意の明白な問題は思えません上記のコードを実装スタック(ラストアウト(FILO))構造が、それもあなたが書いたユニットテストの様々なを介して行うことができます。私たちはポップ方法をポップ使うスタック上のオブジェクトは、オブジェクトがガベージコレクトされることはありませんただし、ポップ方法の一つが、メモリリークの問題は、内部のスタックが保持しているため、プログラムがもはや、これらのオブジェクトへの参照のスタックを使用しているにもかかわらず、存在しませんこれらのオブジェクトへの参照時代遅れ(廃止参照)。言語サポートのガベージコレクションでは、メモリリークは、このメモリリークが実際に無意識のオブジェクトが残っている、非常に微妙です。オブジェクト参照が無意識まで保持されている場合は、ガベージコレクタはこのテーマを扱っていない、それはほんの数、そのようなオブジェクトは、オブジェクトの多くが除外される可能性があり場合でも、オブジェクト参照内の他のオブジェクトを扱うません。パフォーマンスに大きな影響をもたらしガベージコレクションに加えて、それもOutOfMemoryErrorの原因、極端な場合には、ディスクページング(物理メモリと仮想メモリのスワップ・ハード・ディスク・データ)につながります。

(要約)14、抽象メソッドを同時にスタティック(静的)であることができるかどうか、それはまた、修飾されたかどうかを同期させることができる(ネイティブ)ローカルメソッド、ですか?
A:できません。抽象サブクラスオーバーライドする方法の必要性、及び静的メソッドを書き換えることができないので、2つの矛盾しています。ネイティブメソッドがネイティブコード(例えば、Cコード)によって実施される方法であり、抽象メソッドが実装されていない、それが矛盾しています。抽象メソッドに関連した同期方法と実装の詳細は、実装の詳細を伴うので、矛盾しません。

図15は、静的変数およびインスタンス変数間の差を説明します。
回答:静的変数は、メモリ内のクラスの静的変数とコピーを1つだけ作成するオブジェクトの数に関係なく、クラスに属し、クラス変数として知られているstatic修飾子変数を、変更されていない任意のオブジェクトクラスに属しています。変数の例としては、インスタンスに依存しなければなりません、あなたはオブジェクトを通してそれにアクセスする前に、オブジェクトを作成する必要があります。静的変数は、複数のオブジェクトがメモリを共有するように実装することができます。

追加:Java開発は、コンテキスト・クラスおよびツールは、通常、静的メンバがたくさんあります。

16、あなたは静的(スタティック)メソッド内から非静的(非静的)メソッドへの呼び出しを行うことができますか?
静的メソッドを呼び出すときいいえ、静的メソッドは、最初のオブジェクトを作成する非静的メソッドを呼び出すため、オブジェクトのみアクセス静的メンバ初期化されないことができます。

17、どのようにターゲットクローンを達成するには?
A:2つの方法があります
1)クラスオブジェクト;.のCloneableインタフェースとオーバーライドclone()メソッドを実装
するオブジェクトのシリアライゼーションおよびデシリアライゼーションによってクローニング実装直列化インタフェースは、クローンの実際の深さを達成することができる)2。 。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class MyUtil {

    private MyUtil() {
        throw new AssertionError();
    }

    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T clone(T obj) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(obj);

        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);
        return (T) ois.readObject();

        // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义
        // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
    }
}

ここでは、テストコードは次のとおりです。

import java.io.Serializable;

/**
 * 人类
 * @author 骆昊
 *
 */
class Person implements Serializable {
    private static final long serialVersionUID = -9102017020286042305L;

    private String name;    // 姓名
    private int age;        // 年龄
    private Car car;        // 座驾

    public Person(String name, int age, Car car) {
        this.name = name;
        this.age = age;
        this.car = car;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
    }

}
/**
 * 小汽车类
 * @author 骆昊
 *
 */
class Car implements Serializable {
    private static final long serialVersionUID = -5713945027627603702L;

    private String brand;       // 品牌
    private int maxSpeed;       // 最高时速

    public Car(String brand, int maxSpeed) {
        this.brand = brand;
        this.maxSpeed = maxSpeed;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    @Override
    public String toString() {
        return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]";
    }

}
class CloneTest {

    public static void main(String[] args) {
        try {
            Person p1 = new Person("Hao LUO", 33, new Car("Benz", 300));
            Person p2 = MyUtil.clone(p1);   // 深度克隆
            p2.getCar().setBrand("BYD");
            // 修改克隆的Person对象p2关联的汽车对象的品牌属性
            // 原来的Person对象p1关联的汽车不会受到任何影响
            // 因为在克隆Person对象时其关联的汽车对象也被克隆了
            System.out.println(p1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注:クローンの深さだけでなく、達成するためにシリアライズとデシリアライズをクローニングに基づいて、より重要なのは、ジェネリック医薬品によって制限されているクローンを作成する場合は、あなたがチェックアウトすることができます支援シリアライズオブジェクト、このチェックが完了コンパイラです、ありませんで異常動作をスローし、この方式は、クローンクローンオブジェクトクラスを使用する方法よりもはるかに優れています。コンパイル時の問題は、実行時に問題を残すために、常により良い暴露してみましょう。

公開された444元の記事 ウォン称賛15 ビュー10000 +

おすすめ

転載: blog.csdn.net/zt2650693774/article/details/104984621