Java 8インタビューの質問(回答)
1前書き
この記事では、面接中にポップアップする可能性があるJDK8関連の質問をいくつか探ります。
Java 8は、新しい言語機能とライブラリクラスが満載のプラットフォームリリースです。これらの新機能の大部分は、よりクリーンでよりコンパクトなコードを実現することを目的としており、一部の機能はJavaでサポートされたことのない新機能を追加します。
2 Java 8に関する一般的な知識
** Q1. Java 8で追加された新機能
Java 8にはいくつかの新機能が同梱されていますが、最も重要なものは以下のとおりです。
-
Lambda Expressions
– 治療を可能にする新しい言語機能
オブジェクトとしてのアクション
メソッド参照** – 参照することでラムダ式を定義することを可能にします
名前を直接使ってメソッドに
オプション** – 選択性を表現するために使用される特別なラッパークラス
-
機能的インターフェース
– 最大1つの要約を持つインターフェース
方法、実装は、ラムダ式を使用して提供することができる。
デフォルトメソッド** – 完全な実装を追加する機能を私たちに与えてください。
抽象メソッド以外のインタフェース
Nashorn、JavaScriptエンジン** – 実行および実行用のJavaベースのエンジン
JavaScriptコードを評価する
Stream
API ** – 処理を可能にする特別なイテレータクラス
機能的な方法でオブジェクトの集合
Date API ** – 改良された不変のJodaTime風のDate API
これらの新機能に加えて、コンパイラレベルとJVMレベルの両方で、多くの機能強化が内部で行われています。
** 3メソッド参照
** Q1. メソッド参照とは
メソッド参照は、メソッドを呼び出さずにメソッドを参照するために使用できるJava 8構造です。メソッドをラムダ式として扱うために使用されます。それらはいくつかのラムダの冗長性を減らすために構文糖として働くだけです。このように、次のコード:
(o) -> o.toString();
になることができる:
Object::toString();
メソッド参照は、クラス名またはオブジェクト名とメソッド名を区切る二重コロンで識別できます。コンストラクタの参照など、さまざまなバリエーションがあります。
String::new;
静的メソッド参照
String::valueOf;
バウンドインスタンスメソッドのリファレンス:
str::toString;
非バインドインスタンスメソッドの参照
String::toString;
このリンク
とリンク:/java-8-doubleを使用すると、完全な例を使用してメソッド参照の詳細な説明を読むことができます。 -colon-operator[これ]。
Q2. String :: valueOf式の意味は何ですか?
これは、
String
クラスの
valueOf
メソッドへの静的メソッド参照です。
4オプション
Q1.
Optional
とは何ですか?どうやって使えますか?
Optional
は、Java 8の新しいクラスで、オプションの値、つまり存在しないか存在しない値をカプセル化します。それはオブジェクトを包むラッパーであり、あなたはそれを0個または1個の要素のコンテナとして考えることができます。
Optional
には、ラップされた
null
ではなく、特別な
Optional.empty()
値があります。そのため、null許容値の代わりにそれを使用して、多くの場合
NullPointerException
を取り除くことができます。
あなたは
Optional
linkに関する専用の記事を読むことができます:/java-optional[ここ]。
作成者によって設計された、
Optional
の主な目的は、以前は
null
を返すメソッドの戻り型になることでした。このような方法では、戻り値をチェックするための定型コードを記述する必要があり、場合によっては防御的なチェックを忘れる可能性があります。 Java 8では、
Optional
戻り型では、明示的にnullまたはnull以外のラップ値を異なる方法で処理する必要があります。
たとえば、
Stream.min()
メソッドは、一連の値から最小値を計算します。しかし、ストリームが空の場合はどうなりますか?それが
Optional
用ではない場合、メソッドは
null
を返すか、例外をスローします。
しかしそれは
Optional.empty()
かもしれない
Optional
値を返します(2番目のケース)。これにより、このような場合に簡単に対処できます。
int min1 = Arrays.stream(new int[]{1, 2, 3, 4, 5})
.min()
.orElse(0);
assertEquals(1, min1);
int min2 = Arrays.stream(new int[]{})
.min()
.orElse(0);
assertEquals(0, min2);
Optional
がScalaの
Option
のような汎用クラスではないことは注目に値します。エンティティクラスでフィールド値として使用することはお勧めできません。これは、
Serializable
インタフェースを実装していないことによって明確に示されています。
5機能インターフェース
** Q1. 標準ライブラリにいくつかの機能的なインタフェースを記述してください.
java.util.function
パッケージには多くの機能的なインターフェースがありますが、より一般的なものには以下が含まれますが、これらに限定されません。
-
Function
– 引数を一つ取り、結果を返す -
Consumer
– 引数を1つ取り、結果を返しません(
副作用)
**
Supplier
– 引数を取らず結果を返す
-
Predicate
– 引数を1つ取り、ブール値を返します -
BiFunction
– 2つの引数を取り、結果を返します -
BinaryOperator
– これは
BiFunction
に似ていますが、2つ取ります。
引数と結果を返します。 2つの引数と結果は
同じ種類のすべて
**
UnaryOperator
– これは
Function
に似ていますが、単一の
引数と同じ型の結果を返す
機能インターフェースの詳細については、記事リンク/java-8-functional-interfaces[“ Java 8の機能インターフェース”]を参照してください。
Q2. 機能的なインターフェースとは何ですか?機能インターフェースを定義するための規則は何ですか?
機能的なインターフェースとは、抽象メソッドが1つだけで、それ以上、決して少なくないインターフェースです(
default
メソッドはカウントされません)。
そのようなインターフェースのインスタンスが必要な場合は、代わりにラムダ式を使用できます。より正式な言い方をすると、
関数型インタフェース
は、ラムダ式とメソッド参照のターゲット型を提供します。
そのような式の引数と戻り値の型は、単一の抽象メソッドのものと直接一致します。
たとえば、
Runnable
インタフェースは機能的なインタフェースです。
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println("Hello World!");
}
});
あなたは単にすることができます:
Thread thread = new Thread(() -> System.out.println("Hello World!"));
機能インターフェースは通常
@ FunctionalInterface
アノテーションが付けられています。
6. デフォルトの方法
** Q1. デフォルトのメソッドとは何ですか?またいつ使用しますか?
デフォルトメソッドは、実装を持つメソッドです。これは、インタフェースにあります。
デフォルトのメソッドを使用して、すでにインタフェースを実装しているクラスとの下位互換性を維持しながら、インタフェースに新しい機能を追加できます。
public interface Vehicle {
public void move();
default void hoot() {
System.out.println("peep!");
}
}
通常、新しい抽象メソッドがインタフェースに追加されると、すべての実装クラスは新しい抽象メソッドを実装するまで中断します。 Java 8では、この問題はデフォルトのメソッドを使用することで解決されています。
たとえば、
Collection
インターフェースには
forEach
メソッド宣言はありません。したがって、そのようなメソッドを追加すると、単にコレクションAPI全体が壊れることになります。
Java 8ではdefaultメソッドが導入されているので、
Collection
インタフェースはこのインタフェースを実装するクラスに同じ実装を要求することなく
forEach
メソッドのデフォルト実装を持つことができます。
Q2. 次のコードはコンパイルされますか?
@FunctionalInterface
public interface Function2<T, U, V> {
public V apply(T t, U u);
default void count() {
//increment counter
}
}
はい。このコードは、単一の抽象メソッドのみを定義するという機能インターフェース仕様に準拠しているため、コンパイルされます。 2番目のメソッド
count
は、抽象メソッドの数を増やさないデフォルトのメソッドです。
7. ラムダ式
Q1. ラムダ式とは何ですか?またそれは
に使用されます.
非常に簡単に言うと、ラムダ式はオブジェクトとして参照したり渡したりできる関数です。
ラムダ式は、Javaで機能スタイル処理を導入し、コンパクトで読みやすいコードの記述を容易にします。
このため、ラムダ式はメソッドの引数として無名クラスの代わりになります。それらの主な用途の1つは、機能的インターフェースのインライン実装を定義することです。
Q2. ラムダ式の構文と特性を説明する
ラムダ式は、2つの部分から構成されます。パラメータ部分と式部分は、下のように前向き矢印で区切られています。
params -> expressions
すべてのラムダ式には、次のような特徴があります。
-
オプションの型宣言
– でパラメータを宣言するとき
ラムダの左側では、その型を次のように宣言する必要はありません。
コンパイラはそれらの値からそれらを推測できます。だから
int param – > …
and
param – > …
はすべて有効です
オプションの括弧** – 単一のパラメータしか宣言されていない場合は、
かっこで囲む必要はありません。これは
param – > …
そして
(param) – > …
はすべて有効です。しかし、複数のパラメータが
宣言、括弧は必須
省略可能な中括弧** – 式の部分が1つしかない場合
ステートメント、中括弧は必要ありません。これは
param – >を意味します
statement
と
param – > \ {statement;}
はすべて有効です。しかし中括弧
複数のステートメントがある場合は必須
オプションのreturn文** – 式が値を返すとき
中括弧で囲まれているので、returnステートメントは必要ありません。つまり、
(a、b) – > \ {return a b;}
と
(a、b) – > \ {a b;}
はどちらも有効です。
Lambda式の詳細については、https://www.tutorialspoint.com/java8/java8
lambda
expressions.htm[このリンク]および
this one
を参照してください。
8 Nashorn Javascript
Q1. Java 8のNashornとは何ですか?
Nashorn
は、Java 8に同梱されているJavaプラットフォーム用の新しいJavascript処理エンジンです。JDK7まで、Javaプラットフォームは同じ目的でMozilla Rhinoを使用していました。 Javascript処理エンジンとして。
Nashornは、ECMAの正規化されたJavaScript仕様への準拠性が向上し、以前のバージョンよりも優れたランタイムパフォーマンスを提供します。
Q2. jjsとは何ですか?
Java 8では、
jjs
はコンソールでJavascriptコードを実行するために使用される新しい実行可能ファイルまたはコマンドラインツールです。
9ストリーム
Q1. ストリームとはコレクションとはどう違うのですか?
簡単に言うと、ストリームとはイテレータであり、その役割は一連のアクションを受け取ってそれに含まれる各要素に適用することです。
The stream
は、集約操作をサポートするコレクションなどのソースからの一連のオブジェクトを表します。それらは、コレクション処理を単純かつ簡潔にするように設計されています。コレクションとは反対に、繰り返しのロジックはストリーム内に実装されているので、宣言的な処理を実行するために
map
や
flatMap
などのメソッドを使用できます。
もう1つの違いは、
Stream
APIが流暢でパイプライン化が可能であることです。
int sum = Arrays.stream(new int[]{1, 2, 3})
.filter(i -> i >= 2)
.map(i -> i ** 3)
.sum();
また、コレクションとのもう1つの重要な違いは、ストリームは本質的に遅延ロードおよび処理されることです。
Q2. 中間操作と最終操作の違いは何ですか?
ストリーム操作はパイプラインにまとめられてストリームを処理します。すべての操作は中間または端末のいずれかです。
中間操作は
Stream
自体を返す操作で、ストリームに対するそれ以降の操作を可能にします。
これらのオペレーションは常に怠惰です、すなわち、それらはコールサイトでストリームを処理しません、中間オペレーションは端末オペレーションがあるときだけデータを処理することができます。中間操作には、
filter
、
map
、および
flatMap
があります。
端末操作はパイプラインを終了し、ストリーム処理を開始します。端末操作呼び出し中に、ストリームはすべての中間操作を通過します。端末操作には、
forEach
、
reduce、Collect
、および
sum
があります。
この問題を解決するために、副作用のある例を見てみましょう。
public static void main(String[]args) {
System.out.println("Stream without terminal operation");
Arrays.stream(new int[]{ 1, 2, 3 }).map(i -> {
System.out.println("doubling " + i);
return i ** 2;
});
System.out.println("Stream with terminal operation");
Arrays.stream(new int[]{ 1, 2, 3 }).map(i -> {
System.out.println("doubling " + i);
return i ** 2;
}).sum();
}
出力は次のようになります。
Stream without terminal operation
Stream with terminal operation
doubling 1
doubling 2
doubling 3
ご覧のとおり、中間操作は端末操作が存在するときにのみトリガーされます。
Q3.
map
と
flatMap
ストリーム操作の違いは何ですか?
map
と
flatMap
の間には署名に違いがあります。
一般的に言って、
map
操作はその戻り値をその序数型の内側にラップしますが、
flatMap
はしません。
たとえば、
Optional
では、
map
操作は
Optional <String>
typeを返し、
flatMap
は
String
typeを返します。
そのため、マッピング後に値を取得するには、オブジェクトをラップ解除(「フラット化」)する必要がありますが、フラットマッピング後は、オブジェクトが既にフラット化されているため、そのような必要はありません。
Stream
のマッピングとフラットマッピングにも同じ概念が適用されます。
map
と
flatMap
はどちらも、関数を受け取り、この関数をストリームのすべての要素に適用する中間ストリーム操作です。
違いは、
map
の場合、この関数は値を返すのに対し、
flatMap
の場合、この関数はストリームを返すことです。
flatMap
操作は、ストリームを1つに「平坦化」します。
これは、ユーザーの名前と電話のリストのマップを作成し、
flatMap
を使用してすべてのユーザーの電話のリストに「平坦化」する例です。
Map<String, List<String>> people = new HashMap<>();
people.put("John", Arrays.asList("555-1123", "555-3389"));
people.put("Mary", Arrays.asList("555-2243", "555-5264"));
people.put("Steve", Arrays.asList("555-6654", "555-3242"));
List<String> phones = people.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
Q4. Java 8のストリームパイプライン化とは何ですか?
ストリームパイプライン化は、操作を連鎖させるという概念です。これは、ストリームで発生する可能性がある操作を2つのカテゴリ(中間操作と端末操作)に分割することによって行われます。
各中間操作は、実行時にStream自体のインスタンスを返すため、処理パイプラインを形成するデータを処理するために任意の数の中間操作を設定できます。
その後、最終値を返してパイプラインを終了させる端末操作が必要です。
10 Java 8 Date and Time API
Q1. Java 8
の新しいDate and Time APIについて教えてください.
Java開発者にとって長年の問題は、通常の開発者が必要とする日付と時刻の操作に対するサポートが不十分であることです。
java.util.Date
や
SimpleDateFormatter
などの既存のクラスはスレッドセーフではないため、ユーザーに同時実行性の問題が生じる可能性があります。
貧弱なAPI設計は、古いJava Data APIでも現実的です。これは簡単な例です –
java.util.Date
の年は1900年、月は1、日は0から始まります。
これらの問題および他のいくつかの問題により、Joda-Timeなどのサードパーティ製の日付と時刻のライブラリの人気が高まっています。
これらの問題に対処し、JDKでより良いサポートを提供するために、これらの問題がない新しい日時APIがパッケージ
java.time
の下でJava SE 8用に設計されました。
** 11結論+
**
この記事では、Java 8に偏りがある技術面接の質問について、いくつかの非常に重要な質問を取り上げました。 8。
あなたがたった今立ち上がったばかりであっても、Java 8を知らないことは、特にJavaがあなたの履歴書に強く現れているときには、インタビューに参加するのに良い方法ではありません。したがって、これらの質問に対する答えを理解し、さらに研究を進めるために時間をかけることが重要です。
あなたのインタビューで頑張ってください。
次
”
-
«** 前へ