Java 面接の質問集 - 内定をもらいやすくするために推奨される面接の質問
はじめに
ハゲ頭だけが人を強くできる
以前ブログを書いていた時、よく書かれたブログが黙って集められていることに気づきました。最近抜け漏れのチェックをしていて、割と重要な知識点もあったのですが、以前のブログに書いていなかったので、空いた時間を利用して整理してみました(オススメ:JAVA面接問題集) )。
テキストの知識ポイント:
整数定数プール
TCPのアンパックとスティッキング
select,pol,epoll
単純な違いselect、poll、epoll
简单区别jdk1.6以后对Synchronize锁优化
Java内存模型
本文力求简单讲清每个知识点,希望大家看完能有所收获
一、神奇的Integer
前阵子在群上看有人在讨论关于Integer的true或者false问题,我本以为我已经懂了这方面的知识点了。但还是做错了,后来去请教了一下朋友。朋友又给我发了另一张图:
后来发现这是出自《深入理解Java虚拟机——JVM高级特性与最佳实践(第2版)》中的10.3.2小节中~
public class Main_1 { public static void main(String[] args) { Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; Long h = 2L; System.out.println(c == d); System.out.println(e == f); System.out.println(c == (a + b)); System.out.println(c.equals(a + b)); System.out.println(g == (a + b)); System.out.println(g.equals(a + b)); System.out.println(g.equals(a + h)); } }
你们可以先思考一下再往下翻看答案,看看能不能做对。
1.1解题思路
在解这道题之前,相信很多人都已经知道了,在Java中会有一个Integer缓存池,缓存的大小是:-128~127
答案是:
true
false
true
true
true
false
true
简单解释一下:
使用
==
的情况:如果比较Integer变量,默认比较的是地址值。
Java的Integer维护了从
-128~127
的缓存池如果比较的某一边有操作表达式(例如a+b),那么比较的是具体数值
使用
equals()
的情况:无论是Integer还是Long中的
equals()
默认比较的是数值。Long的
equals()
方法,JDK的默认实现:会判断是否是Long类型注意自动拆箱,自动装箱问题。
反编译一下看看:
import java.io.PrintStream; public class Main_1 { public static void main(String[] paramArrayOfString) { Integer localInteger1 = Integer.valueOf(1); Integer localInteger2 = Integer.valueOf(2); Integer localInteger3 = Integer.valueOf(3); Integer localInteger4 = Integer.valueOf(3); Integer localInteger5 = Integer.valueOf(321); Integer localInteger6 = Integer.valueOf(321); Long localLong = Long.valueOf(3L); // 缓存池 System.out.println(localInteger3 == localInteger4); // 超出缓存池范围 System.out.println(localInteger5 == localInteger6); // 存在a+b数值表达式,比较的是数值 System.out.println(localInteger3.intValue() == localInteger1.intValue() + localInteger2.intValue()); // equals比较的是数值 System.out.println(localInteger3.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue()))); // 存在a+b数值表达式,比较的是数值 System.out.println(localLong.longValue() == localInteger1.intValue() + localInteger2.intValue()); // Long的equals()先判断传递进来的是不是Long类型,而a+b自动装箱的是Integer类型 System.out.println(localLong.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue()))); // ... 最后一句在这里漏掉了,大家应该可以推断出来 } }
我使用的反编译工具是jd-gui
- jdk1.6以降の場合 同期ロックの最適化
- は各知識ポイントを簡単に説明するよう努めています
- 、読んだ後に皆さんが何かを得ることができることを願っています1. グループ a の誰かを見ました。少し前 Integer の真偽の問題について議論するとき、私はこの知識点をすでに理解していると思っていました。しかし、それでも間違いを犯したので、友人にアドバイスを求めました。友達が別の写真を送ってくれました:
後になって、これが「Java 仮想マシンの詳細な理解 - JVM の高度な機能とベスト プラクティス (第 2 版)」のセクション 10.3.2 からのものであることがわかりました~
- それについて考えることができますまず答えを読んで正しく答えられるかどうかを確認してください。 1.1 問題解決のアイデア
- この問題を解決する前に、Java には整数キャッシュ プールがあり、キャッシュ サイズは
-128~127
であることを多くの人がすでに知っていると思います。 img src="https://img.php.cn//upload/image/437/714/541/1533177807473997.png" title="1533177807473997.png" alt="Java 面接の質問集 - 内定をもらいやすくするために推奨される面接の質問"/>答えは: - true
- false
- true
- true
- true
- false
public void vectorTest(){ Vector<String> vector = new Vector<String>(); for(int i = 0 ; i < 10 ; i++){ vector.add(i + ""); } System.out.println(vector); }
簡単な説明:
を使用します==
ケース:
- 整数変数を比較する場合、デフォルトの比較は アドレス値です
如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销
但如果存在锁竞争,除了互斥量的开销外,还额外发生了CAS操作,因此在有竞争的情况下,轻量级锁会比传统的重量级锁更慢。
自适应偏向锁:自旋时间不固定
锁消除:如果发现代码是线程安全的,将锁去掉
锁粗化:加锁范围过小(重复加锁),将加锁的范围扩展
轻量级锁:在无竞争的情况下使用CAS操作去消除同步使用的互斥量
偏向锁:在无竞争环境下,把整个同步都消除,CAS也不做。
https://blog.csdn.net/chenssy/article/details/54883355
TCP是基于字节流的,虽然应用层和TCP传输层之间的数据交互是大小不等的数据块,但是TCP把这些数据块仅仅看成一连串无结构的字节流,没有边界;
从TCP的帧结构也可以看出,在TCP的首部没有表示数据长度的字段
1、特殊文字制御
2、ヘッダーの大文字にデータ パケットの長さを追加する
JDK10 がリリースされました。nio についてどれくらい知っていますか?
select和poll
都需要轮询每个文件描述符,epoll
基于事件驱动,不用轮询select和poll
每次都需要拷贝文件描述符,epoll
不用select
最大连接数受限,epoll和poll
最大连接数不受限开发在写代码,此时测试挨个问所有开发者,你写好程序了没有?要测试吗?
- 違いは次のとおりです:
- ヒント: カーネルでの epoll の実装では、イベント ブロックの管理に赤黒ツリーが使用されます
その他の一般的な説明 [1]:
バーテンダー (スレッド)、酔っぱらいのグループが彼の前に横たわり、突然そのうちの 1 人が「飲み物を注いで」と叫び (事件)、あなたは駆け寄って注ぐ彼に飲み物を飲ませて、それから彼を放してください、そして突然別の人がワインを注ぎたいと思ったので、あなたはそれを注ぎに行きます。 時々、ウェイターは多くの人にワインを提供しませんが、ウェイターは暇であり、注ぐことができます。他のことをしたり、携帯電話で遊んだりします。 epollとselectに関して言えば、pollとpollの違いは、後者の2つのシーンでは酔った人々が話さないことと、飲み物が欲しいかどうかを1人ずつ尋ねる必要があり、携帯電話をいじる時間がないことです。 。 io の多重化はおそらく、これらの酔っ払いがウェイターを共有することを意味します。 その他の一般的な説明 [2]: 簡単な例を挙げると (あまり鮮明ではないかもしれませんが)、レストランのウェイター (カーネル) を選択/ポーリングすると、ホテルのオーナー (ユーザー プログラム) に次のように伝えます。このウェイターを知っている人は、ゲストがどのテーブルの料金を払っているのかをボスに伝えてください。上司は各テーブルに行って「支払いますか?」と尋ねなければなりません。 epoll ホテルのウェイター (カーネル) はホテルのオーナー (ユーザー プログラム) に次のように指示します。「ゲスト 1、2、5 はチェックアウトします。ボスはテーブル 1、2、5 に直接行ってお金を受け取ることができます5」。 Java メモリ モデル
JVM ブログ投稿レビュー: JVM はどのようにして始めてから諦めるまでに至ったのですか?
以前 JVM を書いていたとき、- Java メモリ モデル:
- 🎜 変数を操作するときの規則: 🎜🎜🎜🎜Java メモリ モデルでは、すべての 🎜 変数がメイン メモリに格納されることが規定されています 🎜🎜🎜🎜🎜スレッド 🎜ワーキングメモリ🎜は、スレッドによって使用される変数のメインメモリ🎜コピーコピー🎜🎜🎜🎜🎜を保存します。スレッドによる変数のすべての🎜操作🎜は、🎜ワーキングメモリ🎜で実行される必要があります。メインメモリ内の変数を直接読み書きすることはできません🎜🎜🎜🎜 🎜作業メモリからメインメモリへの同期🎜は、次の8つの操作を通じて実装されます: 🎜🎜🎜🎜lock (ロック): メインメモリ内の変数に作用します。メモリ 、変数をスレッド専用としてマークします。 🎜🎜🎜🎜unlock (アンロック): メインメモリ変数に作用して、ロック状態にある変数を解放します。解放された変数のみが他のスレッドによってロックされます。 🎜
read (読み取り): メインメモリ変数に作用し、変数値をメインメモリからスレッドの作業メモリに転送し、後続のロードアクションで使用できるようにします
load (ロード) : 作業メモリ変数に作用し、読み取り操作によってメイン メモリから取得した変数値を作業メモリ内の変数のコピーに置きます。
use (使用): 作業メモリ内の変数に作用し、作業メモリ内の変数値を実行エンジンに渡します。これは、仮想マシンがその値を使用する必要があるバイトコード命令に遭遇するたびに実行されます。変数を操作します。
assign (割り当て): 作業メモリ内の変数に作用し、実行エンジンから受け取った値を作業メモリ内の変数に割り当てます。これは、仮想マシンが値を割り当てるバイトコード命令に遭遇するたびに実行されます。変数に操作します。
store (ストレージ): 作業メモリ内の変数に作用し、後続の書き込み操作のために作業メモリ内の変数の値をメインメモリに転送します。
write (書き込み): メインメモリ内の変数に作用し、作業メモリ内の変数の値からメインメモリ内の変数にストア操作を転送します。
read、load、assign、use、store和write
-
- volatile
- 同期ロック
- volatile
- 同期ロック
- ファイナル
- と呼ばれる原則があります。「happens-before」原則は、いくつかの
を介して同時環境で 2 つの問題を解決するために使用できます。ルール すべての問題 オペレーション間で競合が発生する可能性があるかどうか
これらのルールがあり、私たちの - オペレーションはこれらのルールで定義された範囲内にあります
。操作 A が操作 B より前に確実に実行されることを確認できます (並べ替えの問題は発生しません)
「前に発生する」原則には次のようなものがあります: - モニターロックルール: ロック解除操作は、同じロックに対する後続のロック操作の前に発生します。ここで強調しなければならないのは、同じロックであり、「後で」とは時間的な順序を指します。
- 揮発性変数のルール: 揮発性変数への書き込み操作が最初に発生し、その後に変数への読み取り操作が発生します。ここでの「後で」とは、時間的な順序も指します。スレッド開始ルール: Thread オブジェクトの start() メソッドは、このスレッドのすべてのアクションに先行します。
- スレッド終了ルール: スレッド内のすべての操作は、Thread.join() メソッド、Thread.isAlive() の戻り値などによって終了するときに最初に発生します。は実行を終了しました。
- スレッド割り込みルール: スレッド割り込み() メソッドの呼び出しは、割り込みが発生したスレッドのコードが割り込みイベントの発生を検出する前に最初に発生します。割り込みが発生したかどうかは、 Thread.interrupted() メソッドを通じて検出できます。
- オブジェクトファイナライザールール: オブジェクトの初期化 (コンストラクター実行の終了) は、finalize() メソッドの開始時に最初に行われます。
- 推移性: 操作 A が操作 B の前に発生し、操作 B が操作 C の前に発生した場合、操作 A は操作 C の前に発生すると結論付けることができます。
- 関連記事:
。 Java の Integer は -128~127
のキャッシュ プールを維持します
比較の片側に演算式がある場合 (a+b など)、比較は次のようになります。 特定の値
🎜🎜🎜🎜equals()
の使用: 🎜🎜- 🎜🎜いいえInteger か Long か?
equals()
のデフォルトは 🎜数値🎜 です。 🎜🎜🎜🎜JDK のデフォルト実装である Long の equals()
メソッド: 🎜それが Long 型であるかどうかを判断します🎜🎜🎜🎜🎜🎜自動アンボックス化と自動ボックス化の問題に注意してください。 🎜🎜🎜🎜
jd-gui
です。まだ逆コンパイルを試したことがない場合は、ダウンロードして試してみてください: 🎜🎜🎜 🎜https://github.com/java-decompiler/jd-gui/releases 🎜🎜🎜🎜 2. 同期ロックの最適化メソッドとは何ですか🎜🎜 マルチスレッドの記事レビュー: 🎜🎜🎜🎜ThreadLocal はとてもシンプルです 🎜🎜🎜 🎜3分でマルチスレッド ドアに入ることができます! 🎜🎜🎜🎜スレッドソースコード解析🎜🎜🎜🎜マルチスレッドの基礎知識ポイント!マルチスレッドを学習し、半分の労力で 2 倍の結果を得る方法について読んでください🎜🎜🎜🎜Java ロック メカニズムについて学び🎜🎜🎜🎜AQS を簡単に見てみましょう🎜🎜🎜🎜それについて学ぶにはサブクラスをロックしてください🎜🎜🎜🎜スレッド プール、それについて本当に知りたくないですか? 🎜🎜🎜🎜マルチスレッドのデッドロックはとても単純です🎜🎜🎜🎜Javaマルチスレッドを支援する3人の若者🎜🎜🎜🎜以前マルチスレッドの記事を書いたときに、同期ロックは次の後に発生すると簡単に言いましたjdk1.6 スピン ロックへの適応、ロックの削除、ロックの粗密化、軽量ロック、バイアスされたロックなど、さまざまな最適化があります。 🎜🎜🎜🎜🎜これらの最適化は非常に理解するのが難しいと思っていましたが、実は~~~簡単に理解するだけで簡単に理解できます。 🎜🎜2.1 スピンロックに適応する🎜🎜ロック競合はカーネルモードで行われ、ユーザーモードからカーネルモードへの🎜切り替え🎜が行われますが、これには非常に時間がかかります。 🎜🎜🎜スピンロック🎜が表示される理由は、ほとんどの場合、🎜ロックの占有はカーネルモードに切り替えるのにかかる時間よりも短い時間しか続かない🎜ため、その前にスレッドを待機させてください。カーネル モードに入る 限られた時間内にロックを取得できれば、多くの無駄な時間が回避されます。そうでない場合は、カーネル モードに移行してロックを獲得します。 🎜🎜JDK 1.6 で適応型スピン ロックが導入されました。これは、🎜スピンの時間が固定されず、スピンするかどうかに関係なく、よりスマートになる🎜ことを意味します。 🎜自旋锁在JDK1.4.2中就已经引入,只不过默认是关闭的,可以使用-XX:+UseSpinning
参数来开启,在JDK1.6中就已经改为默认开启了。
2.2锁消除
如果JVM明显检测到某段代码是线程安全的(言外之意:无锁也是安全的),JVM会安全地原有的锁消除掉!
比如说:
public void vectorTest(){ Vector<String> vector = new Vector<String>(); for(int i = 0 ; i < 10 ; i++){ vector.add(i + ""); } System.out.println(vector); }
Vector是默认加锁的,但JVM如果发现vector变量仅仅在vectorTest()
方法中使用,那该vector是线程安全的。JVM会把vector内部加的锁去除,这个优化就叫做:锁消除。
2.3锁粗化
默认情况下,总是推荐将同步块的作用范围限制得尽量小。
但是如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作是出现在循环体中的,频繁地进行互斥同步操作也会导致不必要的性能损耗。
JVM会将加锁的范围扩展(粗化),这就叫做锁粗化。
2.4轻量级锁
轻量级锁能提升程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据。
简单来说:如果发现同步周期内都是不存在竞争,JVM会使用CAS操作来替代操作系统互斥量。这个优化就被叫做轻量级锁。
2.5偏向锁
偏向锁就是在无竞争的情况下把整个同步都消除掉,连CAS操作都不做了!
偏向锁可以提高带有同步但无竞争的程序性能。它同样是一个带有效益权衡(Trade Off)性质的优化,也就是说,它并不一定总是对程序运行有利,如果程序中大多数的锁总是被多个不同的线程访问,那偏向模式就是多余的。在具体问题具体分析的前提下,有时候使用参数-XX:-UseBiasedLocking
来禁止偏向锁优化反而可以提升性能。
2.6简单总结各种锁优化
参考资料:
三、TCP粘包,拆包
这是在看wangjingxin大佬面经的时候看到的面试题,之前对TCP粘包,拆包没什么概念,于是就简单去了解一下。
3.1什么是拆包粘包?为什么会出现?
在进行Java NIO学习时,可能会发现:如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况。
TCP的首部格式:
基于上面两点,在使用TCP传输数据时,才有粘包或者拆包现象发生的可能。
一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包
接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包
拆包和粘包的问题导致接收端在处理的时候会非常困难(因为无法区分一个完整的数据包)
3.2 アンパックとスティッキングの問題を解決する
サブパッケージ化メカニズムには一般に 2 つの 共通 ソリューションがあります:
netty を使用する場合は、解凍と貼り付けの問題を解決するための特別なエンコーダーとデコーダーがあります。
ヒント:UDP にはパケット固着問題はありませんが、パケット損失やパケット障害が発生します。不完全なパッケージは存在せず、受け取ったパッケージはすべて完全に正しいものになります。送信されるデータ ユニット プロトコルは UDP メッセージまたはユーザー データグラムであり、送信時に結合も分割もされません。
4. select、poll、epoll の簡単な違い
NIO レビュー:
これは Linux で I/O 再利用モデルを実装する方法です:
select/poll/epoll
関数の 1 つを呼び出し、複数のファイル記述子がある場合は Return if を渡します。ファイル記述子の準備ができている場合は、タイムアウトになるまでブロックされます。 select/poll/epoll
其中一个函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。
这几个函数是有些区别的,可能有的面试官会问到这三个函数究竟有什么区别:
区别如下图:
两句话总结:
tips:epoll在内核中的实现,用红黑树管理事件块
4.1通俗例子
现在3y在公司里边实习,写完的代码需要给测试测一遍。
select/poll
情况:
epoll
選択してポーリング
epoll
はイベント駆動型であり、ポーリングは必要ありません
select and poll
は毎回ファイル記述子をコピーする必要があります。 epoll
は使用されません
select
接続の最大数は制限されています。epoll と Paul
接続の最大数は制限されていません現在、3 歳は会社でインターン中であり、書かれたコードをテストする必要があります。
select/poll
状況:
開発者はコードを書いています。この時点で、テストはすべての開発者に 1 つずつ尋ねます
epoll
状況:
- 開発者はコードを書き終え、テスターに「コードを書きました。テストしてください。関数は XXX です。」と伝えます。そこでテスターは喜んでバグを探しました。
~~~ 幸いなことに、何人かの熱心なネチズンがそれを私に指摘してくれました。 JVM メモリ構造:
Java メモリ モデルは、同時プロセスでの原子性、可視性、順序付けの処理方法を中心に構築されています
これら 3 つの特性原子性を保証する操作:として上で述べたように、順序性は揮発性ロックと同期ロックによって保証できますが、プログラムを作成するときにコードの順序性を常に意識するわけではありません。実際、Java には、happens-before 原則(happens-before)
- プログラム シーケンス ルール (プログラム順序ルール):スレッドでは、プログラム コードの順序に従って、前に書かれた操作は後ろに書かれた操作より前に発生します。分岐やループなどの構造を考慮する必要があるため、正確には、プログラム コードのシーケンスではなく、制御フローのシーケンスになります。
以上がJava 面接の質問集 - 内定をもらいやすくするために推奨される面接の質問の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4

Java は、初心者と経験豊富な開発者の両方が学習できる人気のあるプログラミング言語です。このチュートリアルは基本的な概念から始まり、高度なトピックに進みます。 Java Development Kit をインストールしたら、簡単な「Hello, World!」プログラムを作成してプログラミングを練習できます。コードを理解したら、コマンド プロンプトを使用してプログラムをコンパイルして実行すると、コンソールに「Hello, World!」と出力されます。 Java の学習はプログラミングの旅の始まりであり、習熟が深まるにつれて、より複雑なアプリケーションを作成できるようになります。
