Java バックエンドの社内面接の質問 (前編)

面接の質問
基本
1. Java言語の特徴は 何ですか
1. 学びやすく豊富なクラスライブラリ
2. オブジェクト指向 ( Javaの最も重要な機能で あり、プログラムの結合性が低くなり、より凝集性が高くなります)
2. オブジェクト指向とプロセス指向の違い
プロセス指向 : 問題を解決するためのステップを分析し、関数を使用してこれらのステップを段階的に実装し、それらを 1 つずつ使用します。
一度だけ呼び出すことができます。高性能のため、シングルチップマイコンや組み込み開発などではプロセス指向開発が一般的です。
オブジェクト指向 : 問題を構成するトランザクションをさまざまなオブジェクトに分解することであり、オブジェクトを確立する目的は各ステップを完了することではありません。
それは、問題全体を解決する過程における何かの動作を説明することです。オブジェクト指向には、 カプセル化、継承、ポリモーフィズム の特徴があります。
セックスは、維持、再利用、拡張が簡単です。低結合のシステムを設計できます。しかし、パフォーマンスの点では、プロセス指向よりも優れています。
低い。
3. 8 つの基本データ型のサイズとそのカプセル化クラス
ノート:
1. Int は基本データ型であり、 Integerは参照型である intのカプセル化クラス です。 intのデフォルト値0 Integer のデフォルト値は
これは null なので、 Integer は 0null を区別できます Java がnullを認識する、この参照がまだ参照していないことを認識します。
オブジェクト。参照を使用する前にオブジェクトを割り当てる必要があります。割り当てられない場合はエラーが報告されます。
2. 基本データ型は宣言時にシステムによって自動的に領域が割り当てられますが、参照型には宣言時にのみ参照領域が割り当てられます。
データ空間は、割り当ての前にインスタンス化によってオープンする必要があります。配列オブジェクトは参照オブジェクトでもあり、配列を別の配列に割り当てます。
配列は参照をコピーするだけなので、ある配列を通じて行われた変更は別の配列にも反映されます。
Alibaba の内部データでは ブールデータ型 が定義されていますが 、そのサポートは非​​常に限られています。Java仮想マシンには、
ブール値 専用のバイトコード命令 Java言語式 によって操作される ブール値は、 コンパイル後に Javaを使用します。
仮想マシンの intデータ型 は置き換えられ、 ブール配列は Java仮想マシンのバイト配列 にエンコードされます
boolean 元素占 8 位。这样我们可以得出 boolean 类型占了单独使用是 4 个字节,在数组中又是 1 个字
节。使用 int 的原因是,对于当下 32 位的处理器( CPU )来说,一次处理数据是 32 位(这里不是指的
32/64 位系统,而是指 CPU 硬件层面),具有高效存取的特点。
4 、标识符的命名规则。
标识符的含义:
是指在程序中,我们自己定义的内容,譬如,类的名字,方法名称以及变量名称等
等,都是标识符。
命名规则:(硬性要求)
标识符可以包含英文字母, 0-9 的数字, $ 以及 _ 标识符不能以数字开头 标
识符不是关键字
命名规范:(非硬性要求)
类名规范:首字符大写,后面每个单词首字母大写(大驼峰式)。 变量
名规范:首字母小写,后面每个单词首字母大写(小驼峰式)。 方法名规范:同变量名。
5 instanceof 关键字的作用
厳密に言えば、 instanceofは Java の二項演算子であり、オブジェクトがクラスのインスタンスであるかどうかをテストするために使用されます。
ために:
obj がオブジェクトで ある場合、 Class は クラスまたはインターフェイスを表します ( obj Classのオブジェクト またはその直接のオブジェクトの場合)
間接的なサブクラス、またはそのインターフェイスの実装クラスの場合、結果は true 返し、それ以外の場合は falseを返します
注: コンパイラは、 obj を 右側のクラス型 に変換できるかどうかをチェックし、変換できない場合は直接エラーを報告します。
型を決定するには、ランタイムに応じてコンパイルを通じて決定します。
ブール値の 結果 = obj クラス のインスタンス
int i = 0 ;
System . out . println ( i instanceof Integer ); // コンパイルは失敗します 。基本型ではなく参照型である必要があります
System . out . println ( i instanceof Object ); // コンパイルは失敗します
整数 integer = 新しい 整数 ( 1 );
システム 出ます println ( 整数 インスタンスオブ 整数 ); //真実
//false , JavaSE 规范 中对 instanceof 运算符的规定就是:如果 obj null ,那么将返
false
System . out . println ( null instanceof Object );
阿里内部资料 6 Java 自动装箱与拆箱
装箱就是自动将基本数据类型转换为包装器类型( int-->Integer );调用方法: Integer
valueOf(int) 方法
拆箱就是自动将包装器类型转换为基本数据类型( Integer-->int )。调用方法: Integer
intValue 方法
Java SE5 之前,如果要生成一个数值为 10 Integer 对象,必须这样进行:
Java SE5ではオートボクシングの機能が提供されている ため、値が10Integerオブジェクト を生成したい場合に必要なのは、
それでおしまい:
面接の質問 1 :
次のコードは何を出力しますか?
操作結果:
なぜそのような結果が出るのでしょうか?出力は、 i1 i2 が 同じオブジェクトを指しているのに対し、 i3 i4 は異なるオブジェクトを指していることを示しています。
象。この時点では、ソース コードを見るだけで真実を知ることができます。次のコードは、 Integer valueOfメソッドの具体的な実装です
整数 i = 新しい 整数 ( 10 );
整数 i = 10;
パブリッククラス Main {
public static void main ( String [] args ) {
整数 i1 = 100 ;
整数 i2 = 100 ;
整数 i3 = 200 ;
整数 i4 = 200 ;
システム 出ます println ( i1 == i2 );
システム 出ます println ( i3 == i4 );
}
}
真実
間違い
Alibaba の内部データ における IntegerCacheクラスの実装は 次のとおりです。
これら 2 つのコードからわかるように、 valueOfメソッド を通じて Integerオブジェクトを作成するとき、値が[-128,127]の間にある場合
IntegerCache.cacheにすでに存在するオブジェクト への参照を返します 。それ以外の場合は、新しい Integer オブジェクトを作成します。
上面的代码中 i1 i2 的数值为 100 ,因此会直接从 cache 中取已经存在的对象,所以 i1 i2 指向的是
同一个对象,而 i3 i4 则是分别指向不同的对象。
面试题 2 :以下代码输出什么
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
private static class IntegerCache {
static final int high ;
static final Integer cache [];
static {
final int low = - 128 ;
// high value may be configured by property
int h = 127 ;
if ( integerCacheHighPropValue != null ) {
// ここでは Long.decode を使用して、次のようなメソッドの呼び出しを回避します。
// Integer のオートボクシング キャッシュを初期化する必要があります
int i = Long デコード ( integerCacheHighPropValue )。 intValue ();
i = 数学 . 最大 ( i , 127 );
// 配列の最大サイズは Integer.MAX_VALUE です
h = 数学 min ( i , Integer . MAX_VALUE - - low );
}
= h ;
キャッシュ = 新しい 整数 [( - ) + 1 ];
int j = ;
for ( int k = 0 ; k < キャッシュ . 長さ ; k ++ )
キャッシュ [ k ] = 新しい 整数 ( j ++ );
}
private IntegerCache () {}
}
Ali 内部データ の実行結果:
理由:
特定の範囲内の整数値の数は有限ですが、浮動小数点数は有限ではありません。
7. オーバーロードと書き換えの違い
オーバーライド _
文字通り、リライトとは、もう一度書き直すことを意味します。実際には、親クラスのメソッド自体をサブクラスで書き換えることになります。息子
クラスは親クラスの元のメソッドを継承しますが、サブクラスが親クラスのメソッドをそのまま継承したくない場合があるため、メソッド名には、
パラメータリストと戻り値の型が 同じ場合 サブクラスのメソッドの戻り値が親クラスのメソッドの戻り値のサブクラスである場合を除く ) 、
メソッド本体が変更または書き換えられます。これが書き換えです。ただし、サブクラス関数のアクセス変更権限を親クラスのアクセス変更権限より低くすることはできないことに注意してください。
パブリッククラス Main {
public static void main ( String [] args ) {
ダブル i1 = 100.0 ;
ダブル i2 = 100.0 ;
ダブル i3 = 200.0 ;
ダブル i4 = 200.0 ;
システム 出ます println ( i1 == i2 );
システム 出ます println ( i3 == i4 );
}
}
間違い
間違い
パブリッククラスの {
public static void main ( String [] args ) {
// TODO 自動生成されたメソッド スタブ
Son s = 新しい Son ();
s SayHello ();
}
public void SayHello () {
システム 出ます println ( "こんにちは" );
}
}
class Son extends Father {   書き換えの概要: 1. 親クラスとサブクラスの間で発生します。 2. メソッド名、パラメーター リスト、戻り値の型 (サブクラス内のメソッドの戻り値の型を除く)
親クラスの戻り値の型のサブクラスである) は同じである必要があります。 3. アクセス修飾子の制限は、オーバーライドされたメソッドのアクセス修飾子より大きくなければなりません。
( public>protected>default>private) 4. オーバーライドされたメソッドは、新しいチェック例外をスローしてはなりません。
より広範囲のチェック例外を示します
オーバーロード ( オーバーロード )
クラス内で、同じ名前のメソッドに異なるパラメーター リストがある場合 ( パラメーターの種類、パラメーターの数、パラメーターの順序が異なる場合)、
同じ ) は過負荷とみなされます。同時に、オーバーロードには戻り値の型に関する要件はありません。戻り値の型は同じでも異なっていても構いませんが、 戻り値の型によって決定することはできません。
過負荷の判定も同じかどうか
オーバーロードの概要: 1. オーバーロード オーバーロードは 、クラス内のポリモーフィズムの表現です。 2. オーバーロードには、同じ名前のメソッドに対して異なるパラメーター リストが必要です (
数値型、パラメーターの数、さらにはパラメーターの順序 ) 3. オーバーロードする場合、戻り値の型は同じでも異なっていても構いません。戻れない
オーバーロードされた関数を区別するための基準としての型
8. 等しい== 違い
@オーバーライド
public void SayHello () {
// TODO 自動生成されたメソッド スタブ
システム 出ます println ( "hello by " );
}
}
パブリッククラスの {
public static void main ( String [] args ) {
// TODO 自動生成されたメソッド スタブ
父 s = 新しい ();
s SayHello ();
s SayHello ( "冬しい" );
}
public void SayHello () {
System . out . println ( "Hello" );
}
public void sayHello ( String name ) {
System . out . println ( "Hello" + " " + name );
}
}
阿里内部资料 ==
== 比较的是变量 ( ) 内存中存放的对象的 ( ) 内存地址,用来判断两个对象的地址是否相同,即是
否是指相同一个对象。比较的是真正意义上的指针操作。
1 、比较的是操作符两端的操作数是否是同一个对象。 2 、两边的操作数必须是同一类型的(可以是
父子类之间)才能编译通过。 3 、比较的是地址,如果是具体的阿拉伯数字的比较,值相等则为
true 、たとえば: int a=10 long b=10L double c=10.0 は すべて地面を指しているため、 ( true の場合) 同じです。
アドレス 10のヒープ
に等しい
すべてのクラスはjava.lang.Objectクラスから継承されるため、 equals は 2 つのオブジェクトの内容が等しいかどうかを比較するために使用されます。
すべてのオブジェクトに適用するには、メソッドがオーバーライドされていない場合でも、 Objectクラス のメソッドが呼び出され、 オブジェクト
のequalsメソッドは ==の判定 を返し ます
要約:
すべての比較が等しい場合は、 equalsを使用し、定数を比較する場合は、 オブジェクトを使用する ため、定数を前に書きます。
等しいオブジェクトは null である可能性があり 、その場合は null ポインタ
Ali のコード仕様では、 equalsのみが使用さ れており、Ali プラグインはデフォルトでそれを認識し、すぐに変更できます。Ali プラグインをインストールすることをお勧めします。
古いコードを確認するには、 「==」を使用して 等号 に置き換えます。
9 Hashcode 的作用
java 的集合有两类,一类是 List ,还有一类是 Set 。前者有序可重复,后者无序不重复。当我们在 set
中插入的时候怎么判断是否已经存在该元素呢,可以通过 equals 方法。但是如果元素太多,用这样
的方法就会比较满。
于是有人发明了哈希算法来提高集合中查找元素的效率。 这种方式将集合分成若干个存储区域,每
个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的
哈希码就可以确定该对象应该存储的那个区域。
hashCode 方法可以这样理解:它返回的就是根据对象的内存地址换算出的一个值。这样一来,当
集合要添加新的元素时,先调用这个元素的 hashCode 方法,就一下子能定位到它应该放置的物理
位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如
果这个位置上已经有元素了,就调用它的 equals 方法与新元素进行比较,相同的话就不存了,不相
同就散列其它的地址。这样一来实际调用 equals 方法的次数就大大降低了,几乎只需要一两次。
10. String String StringBuffer StringBuilderの違いは 何ですか
Ali 内部データ String は 読み取り専用の文字列であり、基本的なデータ型ではなく、オブジェクトです。基礎となるソースコードの観点から見ると、これは 最終的な タイプです。
文字配列、参照される文字列は変更できません。一度定義すると、追加、削除、または変更できません。 文字列 に対する各操作 により、
新しい 文字列 オブジェクト。
+ 演算:
元の string と同じ 新しい StringBuilderオブジェクトをヒープ上に暗黙的に作成し、 appendメソッドを呼び出して次のように綴ります。
+ 以降の文字は接続されます。
StringBuffer StringBuilder は 両方とも、 AbstractStringBuilder 抽象クラスを継承します。
AbstractStringBuilder抽象クラス では、次のことがわかります。
基礎となるレイヤーは可変文字配列であるため、頻繁に文字列操作を実行する場合は、 StringBuffer
操作するのはStringBuilder です さらに、 StringBuffer は メソッドに同期ロックを追加するか、呼び出されたメソッドに同期ロックを追加します。
したがって、スレッドセーフです。 StringBuilder は メソッドに同期ロックを追加しないため、スレッドセーフではありません。
11. ArrayListlinkedList 違い
配列 (array) は インデックス ベースのデータ構造であり、インデックスを使用して配列内のデータを非常に迅速に検索および読み取ります。
配列 からデータを取得する時間計算量は O(1) ですが、データの削除には配列内のすべてのデータを再配置する必要があるため、非常にコストがかかります。
データ ( データを削除した後 後続のすべてのデータを前方に移動する必要があるため )
欠点 : 配列の初期化では初期化の長さを指定する必要があります 指定しないとエラーが報告されます。
たとえば :
List - 繰り返しの要素を含めることができ、インデックスによるアクセスを提供する順序付けされたコレクションであり、 Collectionを継承します
List には、 ArrayListLinkedList という 2 つの重要な実装クラスがあります。
ArrayList: 容量を自動的に増加できる配列として見ることができます
ArrayList toArrayメソッドは 配列を返します。
ArrayList asList メソッドはリストを返します
プライベート最終 文字 [];
/**
※値は文字の格納に使用されます。
*/
char [] ;
int [] a = new int [ 4 ]; // 初期化にはint[] を使用することをお勧めします
int c [] = { 23 , 43 , 56 , 78 }; // 長さ: 4 、インデックス範囲: [0,3]
Alibaba の内部データ ArrayList の基礎となる実装は Array であり、 配列拡張の実装は
LinkList は二重リンク リストであり 要素の追加と削除の際には ArrayListよりも パフォーマンスが優れてい ます 、パフォーマンス はArrayListよりも劣ります。
ArrayList. もちろん これらの比較は大量のデータまたは頻繁な操作を指します。
12. HashMapHashTable 違い
1. 2 つの親クラスが異なります
HashMapは AbstractMapクラス から継承され Hashtable はDictionaryクラスから継承されますただし、両方とも同時に達成されます。
マップ Cloneable (再現可能)、および Serializable (シリアル化可能) の3 つのインターフェイスが実装されています。
2. 外部に提供するインターフェースが異なる
Hashtable は、 HashMap よりも 2 つのメソッドelments()contains()を提供しますelments()メソッドは次のものを継承します。
Hashtable の親クラス Dictionnary elements()メソッドは、この Hashtable内の値の列挙 を返すために使用されます
contains()メソッドは、 に渡された値がHashtableに含まれている かどうかを判断します これはcontainsValue()と同じように機能します事実
上記では、 contansValue() は contains()メソッド を呼び出すだけです
3. null さまざまなサポート
ハッシュテーブル : キー 値も null にすることはできません
HashMap : キーは null にすることもできますが、 キーの一意性が保証されている必要があるため、キーは1 つだけ存在できます。複数存在することもできます。
キー値 に対応する 値は null です
4. 異なるセキュリティ
HashMap は スレッドセーフではありません。マルチスレッドの同時実行環境では、デッドロックなどの問題が発生する可能性があるため、開発者は次のことを行う必要があります。
マルチスレッドのセキュリティ問題に対処しました。
Hashtable はスレッドセーフであり、その各メソッドには synchronized キーワードがあるため、マルチスレッドで直接使用できます。
HashMap はスレッドセーフではあり ませんが、その効率はHashtable よりも はるかに高く 、この設計は合理的です。
分的使用场景都是单线程。当需要多线程操作的时候可以使用线程安全的 ConcurrentHashMap
ConcurrentHashMap 虽然也是线程安全的,但是它的效率比 Hashtable 要高好多倍。因为
ConcurrentHashMap 使用了分段锁,并不对整个数据进行锁定。
5 、初始容量大小和每次扩充容量大小不同
6 、计算 hash 值的方法不同
13 Collection 包结构,与 Collections 的区别
Collection 是集合类的上级接口,子接口有 Set List LinkedList ArrayList Vector Stack
Set
阿里内部资料 Collections 是集合类的一个帮助类,
它包含有各种有关集合操作的静态多态方法,用于实现对各种
集合的搜索、排序、线程安全化等操作。此类不能实例化,就像一个工具类,服务于 Java
コレクション フレームワーク。
14. Javaの 4つのリファレンス 、強いものと弱いもの
強力な参照
強参照は、通常時に最も一般的に使用される参照です。プログラムがメモリ不足 ( OOM ) になると、強参照はリサイクルされません。
道:
ソフトリファレンス
ソフト参照は、プログラムのメモリが不足するとリサイクルされます。
利用可能なシナリオ:
キャッシュが作成されると、作成されたオブジェクトがキャッシュに置かれ、メモリが不足した場合、 JVM は 以前に作成されたオブジェクトを再利用します。
物体。
弱引用
弱参照は、 JVMガベージ コレクターがそれを見つける 限り 、それがリサイクルされることを意味します。
利用可能なシナリオ: Javaソース コード java.util.WeakHashMap キーで 弱参照が使用されています。
参照が必要なくなったら、 JVM が 自動的に処理してくれるため、他の操作を行う必要はありません。
ファントムリファレンス
ファントム参照のリサイクルメカニズムは弱い参照のメカニズムと似ていますが、リサイクルされる前にReferenceQueue に置かれます 知らせ
ああ、他の参照は JVMによって リサイクルされた後に ReferenceQueueに渡されます このメカニズムにより、ファントム参照はほとんどの場合、
参照破壊前の処理に使用されます。さらに、仮想参照を作成するときは、 ReferenceQueueが必要です
使用例:
文字列 str = 新しい 文字列 ( "str" );
システム 出ます println ( str );
// 注:参照 wrf も強参照であり、 SoftReference オブジェクトを指します。
//ここでのソフト参照は、 new String("str") への参照を指します 。これはSoftReferenceクラスのTです
SoftReference < String > wrf = new SoftReference < String > ( new String ( "str" ));
WeakReference < String > wrf = 新しい WeakReference < String > ( str );
PhantomReference < String > prf = new PhantomReference < String > ( new String ( "str" ),
new ReferenceQueue <> ());
アリババ内部データの利用可能なシナリオ :
リソースの解放など、オブジェクトを破棄する前の一部の操作。 ただし、 Object.finalize()でもこれを行うことができます
集団訴訟ですが、この方法は安全ではなく非効率的です
異議申し立てで言及されているいくつかのタイプの参照は、 Reference の 4 つのサブクラスの参照ではなく、オブジェクト自体の参照を指します。
(SoftReference など )
15. 一般的な共通機能
ジェネリックは Java SE 1.5 以降の機能です。
Java Core Technology」 におけるジェネリックの定義は次のとおりです。
汎用 」と は、作成されたコードがさまざまなタイプのオブジェクトで再利用できることを意味します。
ジェネリック はその名の通り、
ジェネリックタイプ 一般的な概念を提供しますが、特定の実装には特定のルールが存在する場合があります。
制約するには、たとえば、私たちがよく使う ArrayList は ジェネリック クラスであり、 ArrayList は さまざまな要素をコレクションとして格納できます。
Integer、String 、さまざまなカスタム型などですが、それを使用する場合は、次のような特定のルールによって制限されます。
Integer 型の要素のみがバンドル コレクションに保存されます。
ジェネリック医薬品を使用するメリットは?
コレクションを例に挙げると、ジェネリックを使用する利点は、整数など、追加される要素のタイプが異なるため、異なるタイプのコレクションを定義する必要がないことです。
型コレクション クラス、浮動小数点型コレクション クラス、文字列コレクション クラス、整数、浮動小数点型、文字列型を格納するコレクションを定義できます。
データ。これは最も重要ではありません。基になるストレージをObject に設定するだけでよく 、追加されたデータはすべて に送信できます。
Object にアップキャストします さらに重要なのは、ルールを通じて、保存されるデータの種類を独自のアイデアに従って制御できることです。
16. Java がオブジェクトを作成する方法は 何通りありますか ?
Java では、 オブジェクトを作成するために次の 4 つの方法が提供されています
new は 新しいオブジェクトを作成します
反射メカニズムを通じて
クローン メカニズムの使用
シリアル化メカニズムを通じて
17. 2 つの異なるオブジェクトが同じ ハッシュコードを持つ可能性はありますか
ハッシュの競合が発生すると、 2 つの等しくないオブジェクト 同じハッシュコード値を持つことになりますハッシュの競合が発生した場合一般に、
それに対処するにはいくつかの方法があります
ジッパー方式 : 各ハッシュ テーブル ノードにはネクスト ポインタがあり複数のハッシュ テーブル ノードはネクストポインタを使用して一方向チェーンを形成できます。
テーブルでは、同じインデックスに割り当てられた複数のノードが、この単一リンクされたリストをストレージとして使用できます
开放定址法 : 一旦发生了冲突 , 就去寻找下一个空的散列地址 , 只要散列表足够大 , 空的散列地址总
能找到 , 并将记录存入
List < Integer > iniData = new ArrayList <> ()
阿里内部资料 再哈希 : 又叫双哈希法 , 有多个不同的 Hash 函数 . 当发生冲突时 , 使用第二个 , 第三个 …. 等哈希函数
计算地址 , 直到无冲突 .
18 、深拷贝和浅拷贝的区别是什么 ?
浅拷贝 : 被复制对象的所有变量都含有与原来的对象相同的值 , 而所有的对其他对象的引用仍然指
つまり 浅いコピーは参照しているオブジェクトではなく問題のオブジェクトのみをコピーします
ディープ コピー : コピーされたオブジェクトのすべての変数には、元のオブジェクトと同じ値が含まれます また、他のオブジェクトを参照する変数は、
コピーされた新しいオブジェクト 元の参照オブジェクトではなくなります つまり ディープ コピーは、コピーされるオブジェクトを参照します。
オブジェクトが複製されます
19. fifinalの用途は 何ですか ?
fifinal は多くのインタビューでよく尋ねられる場所でもありますが この質問は非常に退屈だと思います 。通常は 次の 5 つの点に答える のが良いでしょう
fifinal 変更されたクラスは継承できません
fifinal によって 変更されたメソッドはオーバーライドできません
fifinal によって 変更された変数は変更できません 参照が変更された場合 その参照は不変であり 参照が指す内容は変数であることを意味します
fifinal によって変更されたメソッド の場合 、JVM は 操作効率を向上させるためにメソッド をインライン化しようとします。
fifinal によって 変更された 定数は 、コンパイル中に定数プールに保存されます
さらに コンパイラが fifinalフィールドに対して 従う2 つの並べ替え規則の方が優れています
コンストラクターでの fifinal フィールドの書き込み およびその後の構築されたオブジェクトへの参照の参照変数への代入 これら 2 つの操作
fifinalフィールドを含む オブジェクトへの参照の 最初の読み取り と、それに続く fifinalフィールド の最初の読み取りの間に順序変更 はありません
再注文できます
20. 静電気の用途は 何ですか ?
staticキーワード の 2 つの基本的な使用法は 誰もが知っています : static 変数と static メソッド ( つまり、 static / によって変更される変数)
メソッドはクラスの静的リソースに属し クラス インスタンスによって共有されます
静的変数と静的メソッドに加えて 、静的は 静的ブロックでも使用され 主に初期化操作に使用されます
さらに、 static は主に内部クラスを変更するためにも使用されます 現時点では、これを静的内部クラスと呼びます
最後の使用法は、静的パッケージのインポート つまり import staticです 。import static は、 JDK 1.5以降に導入された新機能 であり 次のように使用できます。
クラス内の静的リソースのインポートを指定するには クラス名を使用する必要はなく リソース名を直接使用できます 次に例を示します
パブリック calss PreCache {
静的 {
// 関連する操作を実行します
}
}
アリの内部情報 21. 3 *0.1 == 0.3 の戻り値は何ですか
false。 一部の浮動小数点数は完全な精度で表現できないためです
22 a=a+b a+=b 有什么区别吗 ?
+= 操作符会进行隐式自动类型转换 , 此处 a+=b 隐式的将加操作的结果类型强制转换为持有结果的类
, a=a+b 则不会自动进行类型转换 . 如:
以下代码是否有错 , 有的话怎么改?
有错误 .short 类型在进行运算时会自动提升为 int 类型 , 也就是说 s1+1 的运算结果是 int 类型 , s1
short 类型 , 此时编译器会报错 .
正确写法:
+= 操作符会对右边的表达式结果强转匹配左边的数据类型 , 所以没错 .
23. try catch fifinally tryreturn がありますがfifinally はまだ実行されます ?
実行、および fifinallyの実行は try戻り よりも前です
静的 Javaをインポートします ラング 数学 * ;
パブリック クラス テスト {
public static void main ( String [] args ){
//System.out.println(Math.sin(20)); 従来のやり方
システム 出ます println ( sin ( 20 ));
}
}
バイト a = 127 ;
byte b = 127 ;
b = a + b ; // 报编译错误 :cannot convert from int to byte
b += a ;
short s1 = 1 ;
s1 = s1 + 1 ;
short s1 = 1 ;
s1 += 1 ;
阿里内部资料 结论:
1 、不管有木有出现异常, fifinally 块中代码都会执行;
2 、当 try catch 中有 return 时, fifinally 仍然会执行;
3 fifinally 是在 return 后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的
値は保存されます。 fifinallyのコードに関係なく 、戻り値は変更されず、以前に保存された値のままです)。そのため、関数
戻り値は、 fifinallyが実行される 前に決定されます。
4. fifinallyにreturn を含めないことをお勧めします そうしないと、プログラムが早期に終了し、戻り値がtryまたはcatchに保存された戻り値と異なります。
24. 例外 エラーのパッケージ 構造
Java がスローできる (Throwable) 構造は、チェック例外 (CheckedException) 、実行時例外の3種類に分けられます。
(RuntimeException) 、エラー (Error)
1. 実行時例外
定義 : RuntimeException とそのサブクラスはランタイム例外と呼ばれます。
特徴 : Java コンパイラはチェックしません。言い換えれば、プログラム内でそのような例外が発生する可能性がある場合、どちらの " throws " も渡されない場合、
声明抛出它 " ,也 " 没有用 try-catch 语句捕获它 " ,还是会编译通过。例如,除数为零时产生的
ArithmeticException 异常,数组越界时产生的 IndexOutOfBoundsException 异常, fail-fast 机制产
生的 ConcurrentModifificationException 异常( java.util 包下面的所有的集合类都是快速失败
的,
快速失败 也就是 fail-fast ,它是 Java 集合的一种错误检测机制。当多个线程对集合进行结构上
的改变的操作时,有可能会产生 fail-fast 机制。记住是有可能,而不是一定。例如:假设存在两个线
プロセス (スレッド 1 、スレッド 2 )、スレッド 1は コレクションA内の要素をIterator を介して走査し、ある時点でスレッド 2 がコレクションA要素を変更します。
構造を変更した場合 (コレクション要素の内容を単に変更するのではなく、構造を変更します)、プログラムはスローします。
ConcurrentModifificationException が異常であるため、 フェイルファスト メカニズムが発生します。このエラーは同時変更例外と呼ばれます。 失敗
安全な場合 java.util.concurrent パッケージ内のすべてのクラスは安全に失敗します。
グループの内容は変更され、イテレータは ConcurrentModifificationExceptionをスローしません 未走査の配列の場合
Web サイト上のコンテンツが変更された場合、反復プロセスに反映される場合があります。これは ConcurrentHashMap イテレータの弱い整合性です。
パフォーマンス。 ConcurrentHashMapの弱い整合性 は主に効率を向上させるためのものであり、これは整合性と効率の間のトレードオフです。
強い一貫性を保つには、どこでもロックを使用する必要があります。グローバル ロックも含めて、 Hashtable や同期された HashMapと 同じです。
了。)等,都属于运行时异常。
常见的五种运行时异常:
ClassCastException (类转换异常)
IndexOutOfBoundsException (数组越界)
NullPointerException (空指针异常)
ArrayStoreException (数据存储异常,操作数组是类型不一致)
阿里内部资料 BufffferOverflflowException
2 、被检查异常
定义 :Exception 类本身,以及 Exception 的子类中除了 " 运行时异常 " 之外的其它子类都属于被检查异
常。
特点 : Java 编译器会检查它。 此类异常,要么通过 throws 进行声明抛出,要么通过 try-catch 进行捕
获处理,否则不能通过编译。例如, CloneNotSupportedException 就属于被检查异常。当通过
clone() 接口去克隆一个对象,而该对象对应的类没有实现 Cloneable 接口,就会抛出
CloneNotSupportedException 异常。被检查异常通常都是可以恢复的。 如:
IOException
FileNotFoundException
SQLException
被检查的异常适用于那些不是因程序引起的错误情况,比如:读取文件时文件不存在引发的
FileNotFoundException 。然而,不被检查的异常通常都是由于糟糕的编程引起的,比如:在对象
引用时没有确保对象非空而引起的 NullPointerException
3 、错误
定义 : Error 类及其子类。
特点 : 和运行时异常一样,编译器也不会对错误进行检查。
当资源不足、约束失败、或是其它程序无法继续运行的条件发生时,就产生错误。程序本身无法修
复这些错误的。例如, VirtualMachineError 就属于错误。出现这种错误会导致程序终止运行。
OutOfMemoryError ThreadDeath
Java 虚拟机规范规定 JVM 的内存分为了好几块,比如堆,栈,程序计数器,方法区等
25 OOM 你遇到过哪些情况, SOF 你遇到过哪些情况
OOM
1 OutOfMemoryError 例外
プログラム カウンターに加えて、仮想マシン メモリの他のいくつかのランタイム領域でも OutOfMemoryError (OOM) 例外が発生します。
可能。
Java ヒープ オーバーフロー:
一般的な例外情報: java.lang.OutOfMemoryError: Java ヒープ スペース
Java ヒープはオブジェクト インスタンスの保存に使用されます。必要なのは、継続的にオブジェクトを作成し、 GC ルートとオブジェクト の間に到達可能なパスがあることを確認することだけです。
これらのオブジェクトをクリアするガベージ コレクション メカニズムを回避すると、オブジェクト数が最大ヒープ容量制限に達した後、メモリ オーバーフロー例外が生成されます。
アリババの内部データにこのような異常が発生した場合、 まず メモリイメージ解析ツール Eclipse Memory Analyzer など)を介して ダンプするのが一般的な方法です。
分析用のヒープ ダンプ スナップショット。メモリ内のオブジェクトが必要かどうかを確認することに重点があり、最初にメモリ リーク (メモリ
リーク) またはメモリ オーバーフロー (Memory Overflflow)
メモリ リークの場合は、ツールを使用して、リークしたオブジェクトから GCRootsまでの参照チェーンをさらに表示できます したがって、漏れているオブジェクトは次のとおりであることがわかります。
GC ルートに関連付けられ 、ガベージ コレクターが自動的にリサイクルできない原因となるパスの種類。
如果不存在泄漏,那就应该检查虚拟机的参数 (-Xmx -Xms) 的设置是否适当。
2 ,虚拟机栈和本地方法栈溢出
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出 StackOverflflowError 异常。
如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出 OutOfMemoryError 异常
这里需要注意当栈的大小越大可分配的线程数就越少。
3 ,运行时常量池溢出
异常信息: java.lang.OutOfMemoryError:PermGenspace
如果要向运行时常量池中添加内容,最简单的做法就是使用 String.intern() 这个 Native 方法。该方法
的作用是:如果池中已经包含一个等于此 String 的字符串,则返回代表池中这个字符串的 String
象;否则,将此 String 对象包含的字符串添加到常量池中,并且返回此 String 对象的引用。由于常量
池分配在方法区内,我们可以通过 -XX:PermSize -XX:MaxPermSize 限制方法区的大小,从而间接
定数プールの容量を制限します。
4 、メソッド領域のオーバーフロー
メソッド領域は、 クラス名、アクセス修飾子、定数プール、フィールドの説明、メソッドの説明など、 Classの関連情報を格納するために使用されます。 も利用可能
メソッド領域に保存された クラスオブジェクトが 時間内にリサイクルされていないか、 クラス 情報が占有しているメモリが構成を超えている可能性があります。
例外情報: java.lang.OutOfMemoryError: PermGenspace
メソッド領域オーバーフローも一般的なメモリオーバーフロー例外であり、ガベージコレクタでクラスを回収する場合の判定条件は非常に厳しい
の。多数の クラスを動的に生成することが多い アプリケーションでは、この点に特に注意してください。
SOF (スタック オーバーフロー StackOverflflow ):
StackOverflflowErrorの定義 : このエラーは、アプリケーションの再帰が深すぎてスタック オーバーフローが発生した場合にスローされます。
通常、スタックはデフォルトで 1 ~ 2m であるため、無限ループまたは多数の再帰呼び出しが発生すると、連続的なスタック プッシュ プロセス中にスタック容量が減少します。
1m を超えると オーバーフローの原因となります。
スタック オーバーフローの理由: 再帰呼び出し、多数のループまたは無限ループ、グローバル変数が多すぎるかどうか、配列、 リスト 、および マップのデータが 大きすぎるかどうか。
26. スレッド、プログラム、プロセスの基本概念を簡単に説明します。そしてそれらの間の関係は何ですか
Alibaba の内部データ スレッドは プロセスに似ていますが、スレッドはプロセスよりも小さな実行単位です。プロセスは複数のプロセスを生成する可能性があります
糸。プロセスとは異なり、同じタイプの複数のスレッドは同じメモリ空間と一連のシステム リソースを共有するため、システムは
スレッド、またはスレッド間の切り替え時の負担がプロセスに比べてはるかに小さいため、スレッドは軽いとも呼ばれます。
大きさのプロセス。
プログラムは 命令とデータを含むファイルであり、ディスクまたはその他のデータ記憶装置に保存されます。つまり、プログラムは静的コードです。
コード。
プロセス はプログラムの実行プロセスであり、システムがプログラムを実行するための基本単位であるため、プロセスは動的です。システムがプログラムを実行する
つまり、創造から運営、そして死に至るまでのプロセスです。簡単に言えば、プロセスとは、計算を行う実行プログラムです。
マシン内の命令は次々に実行され、同時に各プロセスは CPU 時間やメモリ空間などの特定のシステム リソースも占有します。
スペース、ファイル、入出力デバイスなどへのアクセス。言い換えれば、プログラムが実行されると、オペレーティング システムによってメモリにロードされます。
真ん中。スレッドは、プロセスが分割される小さな実行単位です。スレッドとプロセスの最大の違いは、基本的に各プロセスは独立しているのに対し、
同じプロセス内のスレッドは相互に影響を与える可能性が非常に高いため、スレッドの場合は必ずしもそうではありません。別の観点から見ると、プロセスはオペレーティング システムに属します
システムの範囲は、主に同じ期間内であり、複数のプログラムを同時に実行でき、スレッドは同じプログラム内でほぼ同時に実行されます。
一度に複数のブロックを実行します。
27.一部のフィールドを Javaシリアル化でシリアル化したくない 場合はどうすればよいですか?
シリアル化したくない変数の場合は、 transient キーワードを使用して変更します。
transient キーワードの役割は、オブジェクトが逆シリアル化されるときに、インスタンス内でこのキーワードで変更された変数がシリアル化されないようにすることです。
、一時的 に変更された変数値は 永続化されず、復元されません。 transient は 変数のみを変更でき、クラスやメソッドは変更できません
法。
28. JavaIOストリーム について話す
Java には何種類の IO ストリームがありますか ?
流れの流れの方向に応じて、入力フローと出力フローに分けることができます。
操作単位に応じて、バイト ストリームと文字ストリームに分けることができます。
フローはその役割に応じてノードフローと処理フローに分けられます。
Java Io フローには 40以上 のクラスが含まれており、これらのクラスは乱雑に見えますが、実際には非常に規則的であり、クラス間には非常に緊密な関係があります。
Java I0 フローの 40を 超える クラスはすべて、次の 4 つの抽象クラスの基本クラスから 派生します。
InputStream/Reader: すべての入力ストリームの基本クラス。前者はバイト入力ストリーム、後者は文字入力ストリームです。
OutputStream/Writer: すべての出力ストリームの基本クラス。前者はバイト出力ストリーム、後者は文字出力ストリームです。
動作モードによる構造図の分類:
アリババの内部情報は、 操作オブジェクトの構造図に従って分類されます。
アリ内部情報 29 Java IO NIOの違い (補足)
NIO は New IO の略で 、このライブラリはJDK1.4で導入されました。NIOIO は同じ役割と目的を持っていますが、実装方法が異なります。
NIO は 主にブロックを使用するため、 NIO の効率は IO の効率よりもはるかに高くなります Java API では2 セット の NIOが提供されており 、1 つは標準用です。
準入出力 NIO 、もう 1 つはネットワーク プログラミング NIOです
30. Javaリフレクション 原理
1. 定義:
リフレクション メカニズムでは、実行時に、どのクラスについても、このクラスのすべてのプロパティとメソッドを知ることができます。また、どのオブジェクトについても、
任意のメソッドを呼び出すことができます。 Java では 、クラスの名前が指定されている限り、クラスのすべてのプロパティをリフレクション メカニズムを通じて取得できます。
情報があります。
この動的に情報を取得し、オブジェクトのメソッドを動的に呼び出す機能を Java言語 のリフレクション機構と呼びます。
2. 反映メカニズムはどこで使用されますか?
jdbc は典型的な反射です
Class . forName ( 'com.mysql.jdbc.Driver.class' ); // MySQLドライバー クラス をロードします
アリの内部情報 が反映されています。 Hibernate Struts などのフレームワークは 、リフレクションを使用して実装されます。
3. リフレクションの実装:
最初のステップ: Classオブジェクトを取得します。メソッドは 4 つ あります : 1 ) Class.forName("クラスのパス") ; 2 ) クラス名.class 3 ) オブジェクト
Name.getClass () 4 ) 基本型のラッパー クラス。 ラッパー クラスの Typeプロパティを呼び出して、 ラッパー クラスの Class オブジェクトを取得できます。
4. Javaリフレクション を実装するクラス :
1 ) クラス: 実行中の Javaアプリケーション のクラスとインターフェースを示します
オブジェクト情報へのアクセスにはすべて Class クラスが必要です
満たすため。 2 ) フィールド : クラスとインターフェイスに関する属性情報、およびそれらへの動的アクセスを提供します。 3 ) コンストラクター :
クラスの単一のコンストラクターとそのアクセス権に関する情報を提供します。 4 ) メソッド : クラスまたはインターフェイス内のメソッドに関する情報を提供します。
5. 反映メカニズムの長所と短所:
利点: 1 ) 実行時にクラス インスタンスを動的に取得できるため、柔軟性が向上します。2 ) 動的コンパイルと組み合わせることができます。 欠点 : 1 ) リフレクションを使用します。
パフォーマンスは低く、メモリ内のオブジェクトを解析するにはバイトコードを解析する必要があります。解決策: 1. setAccessible(true) を使用する
JDKのセキュリティチェック をオフにして 反映速度を向上させる; 2. クラスのインスタンスを複数回作成する場合、キャッシュがあったほうがはるかに高速になります 3
ReflectASM ツール クラスは、バイトコード生成を通じてリフレクション速度を高速化します 2 )。比較的安全ではなく、カプセル化が破壊されます (パスが
プライベート メソッドとプロパティはリフレクションを通じて取得できます)
31. List、Set、Mapの違い について教えてください。
List ( 順序を処理する優れたヘルパー ) : List インターフェイスは、順序付けされた非一意 (複数の要素が同じオブジェクトを参照できる) のセットを保存します。
物体
セット ( 固有のプロパティに焦点を当てる ): 重複を許可しないコレクション。複数の要素が同じオブジェクトを参照することはできません。
マップ ( キー で検索する専門家 ) :キーと値のペアのストレージを使用します。Map はKeyに関連付けられた値を維持します。2 つのキーが挙げられます
同じオブジェクトを使用しますが、 キーを 繰り返すことはできません。一般的な キーは 文字列型 です が、任意のオブジェクトにすることもできます。
32. Object の一般的なメソッドは 何ですか ? それぞれのメソッドの意味を大まかに話す
java.lang.オブジェクト
Ali の内部情報における該当メソッドの意味は以下の通りです
クローン メソッド
保護メソッドはオブジェクトの浅いコピーを実装します。このメソッドは、 Cloneableインターフェイス が実装されている 場合にのみ呼び出すことができます。それ以外の場合はスローされます。
CloneNotSupportedException 例外。ディープ コピーも Cloneableを実装する必要があり 、そのメンバー変数は参照型です
また、 Cloneableを実装し cloneメソッドをオーバーライドする 必要もあります
fifinalize 方法
このメソッドはガベージ コレクターに関連しており、オブジェクトがリサイクル可能かどうかを判断する最後のステップは、このメソッドが書き換えられているかどうかを判断することです。
法。
イコール メソッド
この方法は非常に頻繁に使用されます。一般に、 等しい == は 同じではありませんが、 Objectでは 同じです。サブクラス 1
通常、このメソッドは書き直す必要があります。
hashCode メソッド
このメソッドはハッシュ検索に使用されます。equalsメソッド が書き換えられると、 通常 hashCodeメソッドも書き換えられます 。このメソッドは一部のハッシュ コードで使用されます。
これはギリシャ関数の コレクションで使用されます
一般に、 obj1.equals(obj2)==true を満たす必要があります obj1.hashCode()==obj2.hashCode() を導入することは可能です が、
hashCode 相等不一定就满足 equals 。不过为了提高效率,应该尽量使上面两个条件接近等价。
JDK 1.6 1.7 默认是返回随机数;
JDK 1.8 默认是通过和当前线程有关的一个随机数 + 三个确定值,运用 Marsaglia’s xorshift
scheme 随机数算法得到的一个随机数。
wait 方法
阿里内部资料 配合 synchronized 使用, wait 方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥
有者,也就是具有该对象的锁。 wait() 方法一直等待,直到获得锁或者被中断。 wait(long timeout)
设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
1. 其他线程调用了该对象的 notify 方法;
2. 其他线程调用了该对象的 notifyAll 方法;
3. 其他线程调用了 interrupt 中断该线程;
4. 時間間隔が終了しました。
この時点で、スレッドをスケジュールできます。スレッドが中断されると、InterruptedException が スローされます
通知 メソッド
このメソッドをsynchronized と組み合わせて使用​​すると、 オブジェクトの 待機キュー 内のスレッドを起動します(同期キュー内のスレッドは
CPUを プリエンプトするスレッド 、待機キュー内のスレッドはウェイクアップを待機しているスレッドを指します)。
通知すべて メソッド
このメソッドをsynchronized と組み合わせて使用​​すると 、このオブジェクトのキューで待機しているすべてのスレッドが起動されます。
要約する
上記のメソッドに精通している限り、 toString メソッド getClassメソッド について説明する必要はありません。調べた対象者
日常生活で使用される多くの メソッド は、その定義を読み取らないものの、依然として使用されています (例: wait()メソッド、
equals() メソッドなど。
一般的な意味: Object は すべてのクラスのルートであり、すべてのクラスの親クラスであり、配列を含むすべてのオブジェクトは Object のメソッドを実装します。
33. Java がオブジェクトを作成する方法は 何通りありますか ?
この質問は簡単なようですが、うまく答えるのは少し複雑です。正しい答えを作成する方法は何でしょうか?
象?
new キーワード を使用します 。これは、オブジェクトを作成する最も一般的に使用される方法でもあります。次に例を示します。
リフレクションを使用してオブジェクトを作成し newInstance()を使用します が、 InstantiationException という2 つの例外を処理する必要があります
不正アクセス例外
クラス オブジェクトはクラス階層のルートです。すべてのクラスにはオブジェクトが含まれています。
スーパークラス。配列を含むすべてのオブジェクトは、このクラスのメソッドを実装します。
ユーザー user=新しいユーザー();
Ali 内部データ ユーザー user=User.class.newInstance();
オブジェクト object=(Object)Class.forName("java.lang.Object").newInstance()
clone メソッド を使用します 。前の質問では、 cloneは Objectのメソッドで ある ため、すべてのオブジェクトがこのメソッドを持ちます。
逆シリアル化を使用してオブジェクトを作成するには ObjectInputStream クラスの readObject()メソッドを呼び出します
オブジェクトを逆シリアル化すると、 JVM が 別のオブジェクトを作成します。 JVM は オブジェクトを作成し、コンストラクターを呼び出しません。
番号。オブジェクトは Serializable インターフェイスを実装しており、オブジェクトをファイルに書き込み、ファイルを読み取ることでシリアル化されたオブジェクトを作成できます。
象。
要約する
オブジェクトの作成方法のキーワード: 新しい 、リフレクション、 クローン コピー、逆シリアル化。
34. Classオブジェクト を取得するには どのような方法がありますか?
クラス オブジェクトとインスタンス オブジェクトを理解しますが、これらはすべてオブジェクトです。
1 つ目:クラス オブジェクトの getClass()メソッドを使用して取得します 。注意深い人なら誰でも、この getClass が Objectクラス あることがわかります。
方法。
2 番目のタイプ: クラスの静的メンバーによって表され、各クラスには暗黙的な静的メンバー classがあります
3 番目の方法: Classクラスの 静的メソッド forName() メソッドを通じて取得します。
35. ArrayListLinkedListの違いは 何ですか ?
配列リスト
利点 : ArrayList は 動的配列に基づいたデータ構造を実装しており、アドレスが連続しているため、データが格納されるとクエリが実行されます。
動作効率が高くなります(メモリ上に連続して配置されます)。
短所 : アドレスが連続しているため、 ArrayList は データを移動する必要があるため、挿入および削除操作の効率が比較的低くなります。
リンクリスト
ユーザー user = 新しい ユーザー ();
//clazz は Userクラスのオブジェクト です
クラス <?> clazz = ユーザー getClass ();
//clazz は Userクラスのオブジェクト です
クラス <?> clazz = ユーザー クラス ;
クラス <?> clazz = クラス forName ( "com.tian.User" );
Ali の内部データ の利点 : LinkedList はリンク リストのデータ構造に基づいており、アドレスは任意であるため、メモリ空間がオープンされるのを待つ必要はありません。
連続したアドレス。操作の追加と削除には、 LinkedList が有利です。 LinkedList は先頭と末尾の操作に適しています
指定した位置にシーンを操作または挿入します。
短所 : LinkedList は ポインタを移動する必要があるため、クエリ操作のパフォーマンスが比較的低くなります。
適用シーン分析
データへのランダム アクセスが必要な場合は、 ArrayListを使用します
データを複数回追加、削除、変更する必要がある場合は、 LinkedListが使用されます
容量が固定されており、容量拡張を行わずに末尾にのみ追加される場合は、 ArrayListが推奨されます
もちろん、ほとんどのビジネス シナリオでは ArrayListを使用するだけで十分ですが、 ArrayListの拡張やスムーズでないこと を避けるように注意する必要があります。
シーケンスの挿入。
36. ArrayList を 使ったことがありますか ? どのような特徴があるのか​​教えてください。
Java に携わっている人なら誰でも、間違いなく使用済み と答えるでしょう それでは、質問の後半、 ArrayListの特性に答えてくださいここから入手可能
いくつかの方法で答えます。
同じ種類の要素データを格納するJava コレクション フレームワークの 1 つは、固定長配列に基づいて実装される可変長コレクション クラスです。
入力データが一定のレベルに達すると、自動拡張が実行され、配列のサイズが拡張されます。
最下層は要素を追加する配列を使用して実装されます。
add(o) を配列の末尾に追加する 場合、追加するデータ量が多い場合は ensureCapacity()を使用する必要があります。
メソッドと同様に、このメソッドの役割はArrayListのサイズ を事前設定することであり 、これにより初期化速度が大幅に向上します。
add(int,o)を使用 て特定の位置に追加すると、多数の配列要素が移動され、拡張がトリガーされる可能性があります。
容量メカニズム。
同時実行性が高い場合、スレッドは安全ではありません。複数のスレッドが ArrayList を同時に操作すると、 予期しない例外やエラーが発生します。
ArrayList は 、コピーできることを示すCloneableインターフェイス を実装しています。 注: ArrayListclone() は実際にコピーします
浅いコピーです。
37. 配列があるのになぜ ArrayListを作るのですか ?
通常、これを使用する場合、挿入するデータの量がわからない場合、通常の配列は非常に恥ずかしいものになります。
初期化する必要がある配列のサイズを把握しており、 要素の数が特定のレベルに達すると、 ArrayList はデフォルトのサイズを使用できます。
その後、容量は自動的に拡張されます。
これは次のように理解できます。私たちがよく言う配列は固定配列ですが、 ArrayList は動的配列です。
38. フェイルファスト とは何ですか ?
Alibaba の内部データの フェイルファスト メカニズムは、 Java コレクション ( Collection ) のエラー メカニズムです。複数のスレッドが同じコレクションのコンテンツを操作する場合
動作中にフェイルファストイベント が生成される場合があります
例: スレッド A が iterator を介して コレクションを走査するとき、コレクションの内容が他のスレッドによって変更された場合
スレッドA が コレクションにアクセスする と、 ConcurrentModifificationException がスローされ、 フェイルファストイベント が発生します。
件。这里的操作主要是指 add remove clear ,对集合元素个数进行修改。
解决办法:建议使用 “java.util.concurrent 包下的类 去取代 “java.util 包下的类
可以这么理解:在遍历之前,把 modCount 记下来 expectModCount ,后面 expectModCount
modCount 进行比较,如果不相等了,证明已并发了,被修改了,于是抛出
ConcurrentModifificationException 异常。
39 、说说 Hashtable HashMap 的区别
本来不想这么写标题的,但是无奈,面试官都喜欢这么问 HashMap
1. 誕生のバージョンが異なり、 Hashtableは Javaがリリースした最初のバージョンであるJDK 1.0 で生まれ HashMapはJDKで生まれました
1.2
2. すべて Map Cloneable Serializable (現在の JDK バージョン 1.8 ) を実装します。
3. HashMap は AbstractMap を継承し AbstractMap はMapインターフェイスも実装しますハッシュテーブルの継承
辞書
4. Hashtableの ほとんどの パブリック メソッドは 、スレッド セーフである 同期フィールドによって変更されます。
HashMap は スレッドセーフではありません。
5. Hashtable キーを null にすることも 値をnullにすることもできません。これは、 Hashtableソース コードputメソッドから取得できます。
値が null と判定された場合は 、直接 null ポインタ例外がスローされ、putメソッド内でキーハッシュ値が計算されることがわかります
の前にキー nullであるとは 判断されません 。つまり、この時点で キー が空の場合でも、null ポインタ例外がスローされます。
6. HashMap キー 値は 両方とも nullにすることができます ハッシュ値を 計算する際に 判定があるのは、
key==null の場合、その hash=0 ; 値がnullであるかどうか については 、まったく判断されていません。
7. Hashtable は オブジェクトのハッシュ値 を直接使用します。 ハッシュ値は、オブジェクトのアドレス、文字列、または番号に基づいてJDKによって計算されます。
int型 の値 次に、剰余メソッドを使用して最終位置を取得します。ただし、除算には非常に時間がかかります
その間、効率は非常に低いです。 計算効率を向上させるために、 HashMap は ハッシュ テーブルのサイズを 2のべき乗に固定します
モジュロ予算を設定する場合、除算を行う必要はなく、ビット演算のみが必要です。ビット演算は除算よりもはるかに効率的です。
8. Hashtable HashMap は両方とも Iterator を使用します 歴史的な理由から、Hashtable はまた、
列挙 方法。
9. デフォルトでは、初期容量は異なります。Hashtable の初期長は 11 、その後、各拡張容量は前の容量になります。
2n+1 ( n は前回の長さ)、 HashMapの初期長 16 で、各展開は元の長さの 2 倍になります。
さらに、 Hashtable の ソースコードのコメントには次のような文があります。
Alibaba 内部データの ハッシュテーブルは同期されています。スレッドセーフな実装が必要ない場合は、
Hashtable の代わりに HashMap を使用することをお勧めします。スレッドセーフ性が高い場合
同時実装が望ましい場合は、使用することをお勧めします
Hashtable の代わりに ConcurrentHashMap を使用します。
一般的な意味: Hashtable はスレッドセーフです。スレッドの安全性 が高く、かつスレッドの安全性が高い場合は、Hashtableの代わりに HashMapを使用することをお勧めします。
送信する場合は、 Hashtableの代わりに ConcurrentHashMapを使用することをお勧めします
この回答が終わった後、インタビュアーは次のように尋ねる可能性があります: HashMap はスレッド セーフではないため、スレッド セーフが必要な場合
パフォーマンスも考慮してください。解決策は何ですか?
ここでの最良の選択は ConcurrentHashMap ですが、面接官は間違いなく話を続けるように求めます。
ConcurrentHashMapの データ構造とその基礎となる原理など
40. HashMapキーには、任意のクラスをキーとして使用 できますか ?
通常、誰もがHashMapキーとして String を最もよく 使用するかもしれませんが、ここではカスタムのキーを使用したいと考えています。
定義したクラスをHashMap キー として使用する場合は 、以下の点に注意する必要があります。
クラスが equals メソッドをオーバーライドする場合は、 hashCode メソッドもオーバーライドする必要があります。
クラスのすべてのインスタンスは、 equals hashCodeに関連するルールに従う必要があります
クラスが equalsを使用しない場合は、 hashCode でそれを使用しないでください
キークラス をカスタマイズするベスト プラクティスは、キー クラスを不変にして、 hashCode 値をキャッシュできるようにすることです。
よりよい性能。不変クラスはまた、 hashCode equals が将来変更されないことを保証し、これにより問題が解決されます。
変数関連の問題も。
41 HashMap 的长度为什么是 2 N 次方呢?
为了能让 HashMap 存数据和取数据的效率高,尽可能地减少 hash 值的碰撞,也就是说尽量把数
据能均匀的分配,每个链表或者红黑树长度尽量相等。
我们首先可能会想到 % 取模的操作来实现。
下面是回答的重点哟:
取余( % )操作中如果除数是 2 的幂次,则等价于与其除数减一的与( & )操作(也就是说
hash % length == hash &(length - 1) 的前提是 length 2 n 次方)。并且,采用二进
制位操作 & ,相对于 % 能够提高运算效率。
这就是为什么 HashMap 的长度需要 2 N 次方了。
42. HashMapConcurrentHashMapの類似点 と相違点
1. すべては キーと値 の形式でデータを保存します。
2. HashMap は スレッドセーフではありませんが、 ConcurrentHashMapは JUCではスレッドセーフ です。
Ali 内部情報 3. HashMap の基礎となるデータ構造は配列 + リンク リストです ( JDK 1.8より前 )。 JDK 1.8 以降、配列 + リンクリスト + 赤と黒
木。リンク リストの要素数が 8 に達すると、リンク リストのクエリ速度は赤黒ツリーほど速くなくなり、リンク リストは赤黒ツリーに変わります。
ブラック ツリーのクエリ速度は高速です。
4. HashMap の初期配列サイズ 16 (デフォルト)、拡張が発生すると、 0.75 *配列サイズ で拡張されます。
許可する;
5. JDK 1.8 より前では、 ConcurrentHashMap はSegment + HashEntryを実現するためにセグメント ロックを使用していました
Segment 配列のサイズのデフォルトは 16 2 の n 乗です 。JDK 1.8以降ではNode + CAS + Synchronizedを使用します。
同時セキュリティの実装を確実にするため。
43. 赤黒の木の特徴は何ですか?
最後の質問の直後に、面接官は赤黒の木について尋ねる可能性があります。赤黒の木のいくつかの特徴を次に示します。
44. Java例外を 通常どのように処理しているかを教えてください
試して、捕まえて、最後に
try ブロックは、例外をスローする可能性のあるコードを監視する役割を果たします。
catch ブロックは、考えられる例外をキャッチして処理する責任があります。
fifinally ブロックはさまざまなリソースのクリーンアップを担当し、例外が発生したかどうかに関係なく実行されます。
このうち try ブロックは必須であり、 catch fifinally には標準例外処理プロセスが少なくとも 1 つあります。
Ali 内部データ は例外をスローする 例外をキャッチする キャッチが成功する (キャッチの例外の型がスローされた例外の型と一致する場合 キャッチは成功します)
例外が処理され、プログラムは実行を継続して例外をスローします 。 → 例外をキャッチします。 キャッチ失敗( キャッチ の例外タイプがスローされた例外タイプと異なる場合)
定数の型が一致しない場合はキャプチャ失敗) 例外が処理されずプログラムが停止する
カスタム例外は開発プロセスで使用されますが、例外のクラス名は共通であるため、通常の状況ではプログラム自体が例外をスローすることはほとんどありません。
通常、例外に関する有用な情報も含まれているため、例外をスローすることを選択する場合は、適切な例外クラスを選択して、理解できるようにする必要があります。
異常な状況を正確に説明するため、現時点ではカスタム例外となることがよくあります。
カスタム例外は通常、 java.lang.Exceptionクラスから継承されます。 ランタイム例外 をカスタマイズする場合は 、継承できます。
java.lang.RuntimeException クラスは、パラメーターなしのコンストラクターと、文字列パラメーターを持つパラメーター化されたコンストラクターを実装します。
ビジネス コードでは、カスタム例外を対象を絞った方法で使用できます。例: ユーザーに特定の権限がない、残高が不足しているなど。
45. ディープコピーとシャローコピーについて話しますか?
浅いコピー ( shallowCopy ) は、既存のメモリ アドレスへのポインタを追加するだけです。
ディープ コピー ( deepCopy ) はポインタを追加して新しいメモリに適用し、追加されたポインタが新しいメモリを指すようにします。
メモリー、
ディープコピーの場合、メモリ解放時にシャローコピーが発生した際に同じメモリを解放してもエラーになりません。
クローン作成モードとプロトタイプ モードを組み合わせるのが最善です。レビューするときは、忘れずにこれらをリンクしてください。
WeChat パブリック アカウントにご注目ください: Java バックエンド テクノロジのフルスタック
JVM の記事
1. 知識のまとめ
Ali の内部データ JVM は Java操作の基礎 です インタビュー中、必ずJVM関連の問題に遭遇します内容は比較的集中していますが深さの要件は比較的高いです
その中で、メモリ モデル クラス ローディング メカニズム 、および GC が 重要な要素であり パフォーマンス チューニング部分はよりアプリケーション指向であり 実践 的な能力に重点が置かれています
実装モードと実行モードの一部は理論的基礎に偏っており 知識ポイントの習得に重点が置かれています
メモリ モデルの 各部分の役割 どのようなデータが保存されているかを理解する必要があります
クラスロード 親委任ロードメカニズム このタイプのクラスは通常、共通ローダーによってロードされます
GC 世代別コレクションの概念と基礎、およびさまざまなガベージ コレクション アルゴリズムのコレクションの概念と適切なシナリオ
パフォーマンス チューニングには 、多くの場合 パラメータ チューニングの基礎となる JVM 最適化パラメータ 一般的に使用されるJVM分析ツールで分析できる問題とその使用方法が影響します
実行モード 解釈 / コンパイル / 混合モードのメリットとデメリット、 Java7 が提供する階層化コンパイル技術 、JIT ジャストインタイムコンパイル技術 、OSR スタック置き換え
つまり 、C1/C2 コンパイラはシーン向け 、C2は サーバーモード 向けと より抜本的な最適化が行われており、新しい技術としてはJava10グラールコンパイラが挙げられます
コンパイラは 、javac ast抽象構文ツリーコンパイラの最適化、および実行時の最適化のコンパイル プロセスを最適化します
2. 詳細な知識ポイント:
1. JVMメモリモデル
阿里内部资料 线程独占 : , 本地方法栈 , 程序计数器 线程共享 : , 方法区
2 、栈:
又称方法栈 , 线程私有的 , 线程执行方法是都会创建一个栈阵 , 用来存储局部变量表 , 操作栈 , 动态链接 ,
法出口等信息 . 调用方法时执行入栈 , 方法返回式执行出栈 .
3 、本地方法栈
与栈类似 , 也是用来保存执行方法的信息 . 执行 Java 方法是使用栈 , 执行 Native 方法时使用本地方法栈 .
4 、程序计数器
現在のスレッドによって実行されたバイトコードの位置を保存します 各スレッドは動作時に独立したカウンタを持ち Javaメソッドの実行 のみを行います
ネイティブ メソッドで は、 プログラム カウンタは空です
5. ヒープ
JVMメモリ管理 の最大の部分は スレッドによって共有されます その目的はオブジェクト インスタンスを保存することであり、必要なオブジェクト インスタンスのほぼすべてがここに配置されます
ヒープに使用可能な領域がない場合 OOM例外が スローされます オブジェクトのライフサイクルに従って、JVM はオブジェクトを世代ごとに管理しガベージが返されます。
ガベージ コレクション管理用のコレクター
6. メソッド領域:
非ヒープ領域とも呼ばれ 、仮想マシンによってロードされたクラス情報 定数静的変数リアルタイム コンパイラによって最適化されたコードなどの データを格納するために使用されます
1.8 の永続生成と 1.8 のメタスペースは両方ともメソッド領域の実装です。
7. JVMメモリの 可視性
Ali 内部データ JMM は、 プログラム内の変数のアクセス ルールを定義します スレッドは、独自の作業メモリ内の変数に対してのみ操作でき 直接操作することはできません。
メイン メモリの操作 命令の並べ替えにより読み取りと書き込みの順序が乱されるためJMM は アトミック性 可視性、および順序の保証を提供する必要があります
3. クラスのロードとアンロードについて話す
ロードプロセス
このうち、 検証 準備 解析 を総称してリンクと呼びます。
クラスの完全修飾名を使用して ロードし そのようなバイトコード ファイルを検索し そのバイトコード ファイルを使用して Class オブジェクトを作成します
クラスファイル 現在の仮想マシンの要件を満たしており仮想マシン自体の安全性が危険にさらされないことを確認します
メモリ割り当ての 準備をし 静的に変更されたクラス変数 にメモリを割り当て 初期値(0またはnull) を設定します。fifinal変更を含まない静的変数
amount 。fifinal変数はコンパイル時に割り当てられるため です
定数プール内のシンボリック参照を直接参照に置き換えるプロセスを 解析します 直接参照は、ターゲットまたは相対オフセットへの直接のポインタです。
など _
初期化では 主に静的ブロックの実行と静的変数の割り当てが完了します 最初に親クラスを初期化し 次に現在のクラスを初期化します クラスのアクティブな使用のみが行われます。
初期化されます
トリガー条件には クラスのインスタンスを作成するとき クラスの静的メソッドまたは静的変数にアクセスするとき Class.forName を使用して クラスを反映するときが含まれます。
または サブクラスが初期化された とき
Java 独自のローダー によってロードされたクラスは、仮想マシンのライフサイクル中にアンロードされず ユーザー定義のローダーのみがロードされます。
クラスはアンロードできます
Ali の内部情報 1. ロードメカニズム - 親委任モード
親委任モード つまり、ローダーがクラスをロードするとき、最初にリクエストをその親クラス ローダーに委任して、 最上位の起動クラス ローダー まで実行します
親クラス ローダーがロードを完了できれば、正常に戻ります そうでない場合は、子クラス ローダーが独自にロードを試みます 。*
利点 :
1. クラスの繰り返しロードを避ける
2. JavaのコアAPIの改ざんを 防止する
2. 世代リサイクル
世代別リサイクルは 2 つの事実に基づいています ほとんどのオブジェクトはすぐに使用されなくなり 一部のオブジェクトはすぐには使用できなくなるが 長期間使用できないことになります。
部屋
若い世代 -> マーク - コピー 古い世代 -> マーク - クリア
3. リサイクルアルゴリズム
アリ内部 データ G1アルゴリズム
1.9 以降のデフォルトのガベージ コレクション アルゴリズムは 、一時 停止を減らしながら高い回復率を特徴とし 一度に すべてではなく 一部のみがクリーンアップされます。
一時停止時間が長すぎないように 内部 の増分クリーニングを行う
若い世代と古い世代の物理的な分割はキャンセルされますが 依然として世代別コレクターに属しており アルゴリズムはヒープをいくつかの論理領域 (リージョン)に分割します
若い世代として使用されるもの 古い世代として使用されるもの および巨大なオブジェクトを格納するためのパーティションがあります
CMSと 同様 すべてのオブジェクトを走査し 参照をマークし オブジェクトをクリアした後で領域をコピーおよび移動して、 断片化された空間 を統合します
Young Generation Recycling :並列レプリケーションで 、レプリケーション アルゴリズム 並列コレクション StopTheWorld が採用されています。
古い世代でリサイクル 若い世代でリサイクルされる
最初のマーキングは、ヒープの ルートオブジェクト のマーキングを完了し StopTheWorldが同時に実行され ます 。GCスレッドとアプリケーション スレッドは同時にマークされます最終マーキングは、
3 色のマーキング サイクルが完了したら StopTheWorld.コピー/クリアにより、リサイクル可能なスペースが増加したリサイクル エリアが優先されます
b . ZGC アルゴリズム
上記の高効率ガベージ コレクション アルゴリズムは、 大規模なヒープ メモリ向けに設計されており TBレベルのヒープ を処理でき 10 ミリ秒未満のリカバリ停止を実現できます。
トン時間
影付きポインタ
読み取りバリア
同時処理
地域に基づいて
メモリ圧縮 編成
ルート マーク: ルート オブジェクトをマークする と、 StopTheWorld が 実行されます。 同時マーク: 読み取りバリアを使用して、アプリケーション スレッド 一緒にマークを実行します。
StopTheWorld が発生します。 クリアすると、使用不可としてマークされたオブジェクトがクリーンアップされます 。ルートの再配置: 生き残った オブジェクトを次の場所に 移動します。
大きなメモリ空間を解放し 断片化を減らします 。再配置により 最初は StopTheWorldが実行されます が、それは再配置セットとオブジェクトのアクティブ セットの合計によって異なります。
スケール : 同時再配置は同時マーキングと似ています
4. JVMのメモリ モデルを 簡単に説明します。
Ali 内部情報1. JVM メモリ モデルの概要
JVM は、 アプリケーションの実行に使用されるさまざまなランタイム データ領域を定義します。 一部の領域はJVM で開始および破棄され 、別の領域は JVM で開始および破棄されます。
これらの領域のデータはスレッドに依存せず、スレッドによって作成および破棄されます。 jvmメモリ モデル の全体的なアーキテクチャは次のとおりです: ( Oracleからの抜粋)
公式サイト
JVM が Javaプログラム を実行するとき 、JVM は管理するメモリをいくつかの領域に分割し、各領域には独自の目的と作成があります。
時間を破壊する。以下の図に示すように、スレッドのプライベート領域と共有領域の 2 つの部分に分けることができます。下の図は私自身の理解に基づいて描いたものです
JVM メモリモデルのアーキテクチャ図:
Ali 内部データ JVM メモリはスレッド専用領域とスレッド共有領域に分割されます
スレッドのプライベート領域
1. プログラムカウンター
同時スレッド数が CPU数 またはコア数を超える場合、タイム スライス ポーリングによって CPU 時間リソースを割り当てる必要があり、必然的に
スレッド切り替えが発生します。このとき、各スレッドは次に実行される命令を記録するために独自のカウンターを必要とします。実行された場合
これは JAVAメソッドであり、カウンタは 実行中の Java バイトコードのアドレスを記録します。 ネイティブ メソッドが実行されると、カウンタは次のようになります。
ヌル。
2. 仮想マシンスタック
スレッドプライベート。スレッドと同時に作成されます。 Javaメソッドの実行 を制御するメモリ モデル メソッドを実行するたびに、
フレームスタックは、メソッドの変数テーブル、オペランドスタック、ダイナミックリンクメソッド、戻り値、戻りアドレスなどの情報を格納するために使用されます。スタックのサイズによって決まります
メソッド呼び出しの到達可能な深さを決定します (再帰のレベルの数、または他のメソッドのレイヤーが何層ネストされているか、 -Xss パラメーターで仮想マシンを設定できます)
スタックサイズ)。スタックのサイズは固定することも、動的に拡張することもできます。要求されたスタックの深さが利用可能な最大の深さより大きい場合、
stackOverflflowError をスローします 。スタックは動的に拡張可能だが、拡張をサポートするメモリ空間がない場合は、スローします。
メモリ不足エラー jclasslibツール を使用して、クラスファイルの構造 を表示します 次の図はスタック フレーム構造図です。
Ali 内部情報 3 、ローカル メソッド スタック
仮想マシン スタックに似ています。ただし、 Javaメソッドではなく、ネイティブ メソッド ( C言語) を提供します 仕様には無いので、
必須要件。仮想マシンごとに実装方法が異なります。
スレッド共有領域
1. メソッドエリア
スレッドによって共有され、定数、静的変数など、仮想マシンによってロードされ、ジャストインタイム コンパイラによってコンパイルされたクラスのメタデータ情報を保存するために使用されます。
コード。世代に分けたい場合は、永続世代 (古い世代) と見なすことができます。以前のクラスのほとんどは "静的"であり 、アンロードまたは収集されることはほとんどありませんでした。現在はリサイクルされ、破棄されます。
定数と役に立たないクラス。このうち、実行時定数プールには、コンパイルによって生成される各種定数が格納されます。 (ホットスポット 仮想マシンがクラスを決定する場合
の定義情報は使用されず、再利用されます。リサイクルの基本条件は少なくとも次のとおりです。このクラスのすべてのインスタンスがリサイクルされ、
このクラスをロードした ClassLoader は リサイクルされます)
2. ヒープ
オブジェクトのインスタンスと配列のストレージは、ガベージ コレクションの主な領域であり、新世代と旧世代に分かれています。新しく作成されたオブジェクトは新しい世代にあります
Eden 領域 では GC後、 新世代の S0 領域に入り、 GC後に新世代のS1領域に入り、 15 回のGC後も存在します。
老後へ。これは固定されたものではなく、リサイクルメカニズムに従って分割されます。ヒープ領域がインスタンスの割り当てに十分でない場合は、
メモリ不足エラー
アリの内部データ ヤングジェネレーションは 図中 エデン+From Space ( s0 ) +To Space(s1)
Eden は 新しいオブジェクトを保管します
Survivor Spacesが 2 つあり、各ガベージ コレクション (s0+s1) で生き残るオブジェクトが保存されます。
旧世代 終身世代は、 絵の中の 古いスペースです
主にライフサイクルの長い存続オブジェクトをアプリケーションに保存します
5. ヒープとスタックの違いについて話す
スタックはロジックを表す実行時単位であり、ヒープ内の基本データ型とオブジェクト参照を含み、断片化のない連続領域に配置されます。
これは、複数のスタック (基本データ型、参照、メンバー内の参照オブジェクトを含む) で共有できるデータを表すストレージ ユニットです。
領域は連続しておらず、断片が存在します。
1. さまざまな機能
栈内存用来存储局部变量和方法调用,而堆内存用来存储 Java 中的对象。无论是成员变量,局部变
量,还是类变量,它们指向的对象都存储在堆内存中。
2 、共享性不同
栈内存是线程私有的。 堆内存是所有线程共有的。
3 、异常错误不同
如果栈内存或者堆内存不足都会抛出异常。 栈空间不足: java.lang.StackOverFlowError 。 堆空间
不足: java.lang.OutOfMemoryError
4 、空间大小
栈的空间大小远远小于堆的。
6 、 什么时候会触发 FullGC
除直接调用 System.gc 外,触发 Full GC 执行的情况有如下四种。 1. 旧生代空间不足 旧生代空间只有
在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行 Full GC 后空间仍然不
足,则抛出如下错误: java.lang.OutOfMemoryError: Java heap space 为避免以上两种状况引起
FullGC 場合、チューニング時にオブジェクトが マイナー GCフェーズで リサイクルされるようにし、オブジェクトが新しい世代で長期間存続するようにします。
大きすぎるオブジェクトや配列を作成する場合。
2. Permanet Generation スペースがいっぱいです。PermanetGeneration には いくつかの クラス 情報が保存されます。
ロードするクラス、反映されるクラス、および呼び出すメソッドが多数ある場合、 永続世代が いっぱいになる可能性があります。
CMS GCの場合 Full GC が実行されます Full GC後もリサイクルできない場合JVM は次のエラー メッセージをスローします。
メッセージ: java.lang.OutOfMemoryError: PermGen space フルPerm Genによって引き起こされるFull GC現象 を回避するには 、次のことができます。
採用される方法は、 Perm Genスペースを増やすか、 CMS GC に切り替えることです
アリ内部情報3. CMS GC 中に 昇格失敗 同時モード障害が 発生しました旧世代GCにCMS をご利用の 方へ
プログラムに関する限り、 GCログ 昇格の失敗 同時モードの失敗があるかどうかに特に注意してください
これら 2 つの条件が発生すると、 フル GC がトリガーされることがあります Promotionfailedは、 マイナー GC の進行中に 生存者スペース
オブジェクトは古い世代にのみ配置でき、現時点では古い世代を削除することはできません。 同時モードの失敗は、次のコマンド を実行すると発生します。
CMS GC のプロセス中に、 同時に古い世代に配置されるオブジェクトがありますが、この時点では古い世代のスペースが不足しています。対策は以下の通りです。
Survivorspace 、古い世代スペース、または同時 GC を トリガーする比率を削減しますが JDK 5.0以降6.0 以降のバージョンでは、
JDK bug29 导致 CMS remark 完毕后很久才触发 sweeping 动作。对于这种状况,可通过设置 -
XX:CMSMaxAbortablePrecleanTime=5 (单位为 ms )来避免。
4. 统计得到的 Minor GC 晋升到旧生代的平均大小大于旧生代的剩余空间 这是一个较为复杂的触发
情况, Hotspot 为了避免由于新生代对象晋升到旧生代导致旧生代空间不足的现象,在进行 Minor
GC 时,做了一个判断,如果之前统计所得到的 Minor GC 晋升到旧生代的平均大小大于旧生代的剩
余空间,那么就直接触发 Full GC 。 例如程序第一次触发 MinorGC 后,有 6MB 的对象晋升到旧生
代,那么当下一次 Minor GC 发生时,首先检查旧生代的剩余空间是否大于 6MB ,如果小于 6MB
次に、 Full GCを実行します 新しい世代で PSGCが採用されると 、方法が少し異なり、 Minor GCの後に PS GCもチェックされます
上記の例の最初の マイナー GCの後 PS GC は、この時点で古い世代の残りのスペースが 6MB より大きいかどうかを確認し 、6MB 未満の場合はトリガーされます。
古い世代のコレクションを送ります。 上記の4 つの状況 に加えて RPCまたは管理 RMI を使用する Sun JDKアプリケーションの場合、デフォルト
デフォルトでは、 フル GC は1 時間に 1 回実行されます -java経由で起動時に利用可能
Dsun.rmi.dgc.client.gcInterval=3600000で フル GC実行の間隔 を設定するか、 -XX:+を渡します
DisableExplicitGC は、 RMI がSystem.gcを呼び出すことを 禁止します
7. Java仮想マシン とは何ですか ? Java がプラットフォームに依存しないプログラミング言語」と呼ばれるのはなぜですか?
Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程。 Java 源文件被编译成能被 Java 虚拟机执行的字
节码文件。 Java 被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独
重写或者是重新编译。 Java 虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特
性。
8 Java 内存结构
阿里内部资料 方法区和对是所有线程共享的内存区域;而 java 栈、本地方法栈和程序员计数器是运行是线程私有
的内存区域。
Java 堆( Heap
, Java 虚拟机所管理的内存中最大的一块。 Java 堆是被所有线程共享的一块内
存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实
例都在这里分配内存。
方法区( Method Area
, 方法区( Method Area )与 Java 堆一样,是各个线程共享的内存区
域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数
据。
程序计数器( Program Counter Register
, 程序计数器( Program Counter Register )是一块
较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。
JVM 栈( JVM Stacks
, 与程序计数器一样, Java 虚拟机栈( Java Virtual Machine Stacks )也是
线程私有的,它的生命周期与线程相同。虚拟机栈描述的是 Java 方法执行的内存模型:每个方
法被执行的时候都会同时创建一个栈帧( Stack Frame )用于存储局部变量表、操作栈、动态
阿里内部资料 链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机
栈中从入栈到出栈的过程。
本地方法栈( Native Method Stacks
, 本地方法栈( Native Method Stacks )与虚拟机栈所发
挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服
务,而本地方法栈则是为虚拟机使用到的 Native 方法服务。
9 、说说对象分配规则
对象优先分配在 Eden 区,如果 Eden 区没有足够的空间时,虚拟机执行一次 Minor GC
大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在
Eden 区和两个 Survivor 区之间发生大量的内存拷贝(新生代采用复制算法收集内存)。
长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了 1
Minor GC 那么对象会进入 Survivor 区,之后每经过一次 Minor GC 那么对象的年龄加 1 ,知道达
到阀值对象进入老年区。
动态判断对象的年龄。如果 Survivor 区中相同年龄的所有对象大小的总和大于 Survivor 空间的
半分、この年齢以上のオブジェクトは古い世代に直接入ることができます。
スペース割り当ての保証。 マイナー GC が実行されるたびに JVM は Survivor領域から古い領域に移動されたオブジェクトの平均サイズを 計算します。
この値が古い領域に残っている値のサイズより大きい場合は Full GCが実行され 、小さい場合はチェックが実行されます。
HandlePromotionFailure 設定。 trueの場合はモニター GC のみ が実行され、 false の 場合は フル GCが実行されます
10. JVM がクラスファイルをロードする原理的なメカニズム について説明してください
JVMでのクラスのロードは 、クラス ローダー ( ClassLoader ) とそのサブクラスによって 実装されます。Java クラス ローダーは重要です。
実行時にクラス ファイル内の クラスを検索してロードする役割を担う Java ランタイム システム コンポーネント Javaのクロスプラットフォームの性質 により 、コンパイルされた
翻訳された Java ソース プログラムは実行可能プログラムではなく、1 つ以上のクラス ファイルです。 Java プログラムで特定のクラスを使用する必要がある場合、
JVM は、 このクラスがロード、リンク (検証、準備、解析) され、初期化されていることを確認します。クラスのロードとは、クラスの .class ファイルをロードすることを指します。
ファイル内のデータは、通常、バイト配列を作成して.class ファイルに読み込み、ロードされたクラスに対応するクラスを生成することによってメモリに読み込まれます。
クラス オブジェクト。ロードが完了した後、 Class オブジェクトは完成していないため、この時点ではクラスはまだ使用できません。クラスのロード時に接続を入力します
ステージには、検証、準備 (静的変数にメモリを割り当て、デフォルトの初期値を設定する)、および解決 (シンボルを参照する) が含まれます。
直接引用符に置き換えます) を 3 つのステップで実行します。最後に、 JVM は 以下を含むクラスを初期化します。 1) クラスに直接の親クラスがあり、これが
クラスが初期化されていない場合は、最初に親クラスを初期化します。2 ) クラスに初期化ステートメントがある場合は、これらの初期化ステートメントを順番に実行します。
文。クラスのロードは、ルート ローダー ( BootStrap )、拡張ローダーなどのクラス ローダーによって行われます。
( Extension )、システムローダー ( System )、およびユーザー定義クラスローダー ( java.lang.ClassLoader のサブクラス)
親切)。 Java 2 ( JDK 1.2 ) 以降 、クラスロードプロセスには親委任メカニズム ( PDM ) が採用されています。 PDM は より優れた保証を提供します
Java プラットフォームのセキュリティ。このメカニズムでは、 JVM に付属する ブートストラップが ルート ローダーであり、他のローダーには 1 つのみのローダーがあります。
親クラスローダー。クラスのロードは、まず親クラスローダーにロードを要求し、親クラスローダーが無力な場合、その子クラスローダーが独自に追加します。
ロード。 JVM は、 Javaプログラム への ブートストラップへの参照を提供しません以下に、いくつかのクラスローダーについて説明します。
Bootstrap : 通常はローカル コードで実装され、 JVM 基本コア クラス ライブラリ ( rt.jar ) のロードを担当します。
Extension : java.ext.dirsシステム プロパティで指定されたディレクトリ からクラス ライブラリをロードします 。その親ローダーはBootstrapです
Ali 内部データ System : アプリケーション クラス ローダーとしても知られ、その親クラスは Extensionです 最も広く使用されているクラスローダーです。環境によって変わる
クラス パス またはシステムプロパティ java.class.pathで指定されたディレクトリに記録されたクラスは 、ユーザー定義ローダーのデフォルトです。
親ローダー。
11. Javaオブジェクトの作成プロセス について話す
1. JVM は、 新しいオブジェクトを作成する命令を検出すると、まずこの命令のパラメータをクラスのシンボルとして定数プールに定義できるかどうかをチェックします。
参照番号。次に、このクラスをロードします (クラスのロードプロセスについては後で説明します)。
2. オブジェクトにメモリを割り当てます。1 つ は「 ポインタ衝突 、もう 1 つは フリー リスト 、そして最後に一般的に使用される方法は ローカル スレッド バッファ割り当て」です。
(TLAB)付き」
3. オブジェクトヘッダを除くオブジェクトメモリ空間を 0に初期化します。
4. オブジェクトヘッダーに必要な設定を行います
12. クラスのライフサイクルをご存知ですか?
クラスのライフサイクルには、ロード、接続、初期化、使用、アンロードの部分が含まれます。そのうちの最初の 3 つはクラスのロードのプロセスです
以下に示すように;
クラスのバイナリデータをロード、検索してロードし、 Javaヒープ内にクラス java.lang.Classのオブジェクト を作成します。
接続には、検証、準備、初期化の 3 つの部分が含まれています。 1 ) 検証、ファイル形式、メタデータ、バイトコード、
シンボル参照の検証; 2 ) クラスの静的変数を準備し、メモリを割り当て、それらをデフォルト値に初期化します; 3 ) 解析、put
クラス内のシンボリック参照は直接参照に変換されます
初期化。クラスの静的変数に正しい初期値を割り当てます。
使用、 プログラムで使用される 新しいオブジェクト
アンロード、ガベージコレクションの実行
13. Javaのオブジェクト構造 を簡単に説明します
Java オブジェクトは、オブジェクト ヘッダー、インスタンス データ、および位置合わせパディングの 3 つの部分で構成されます。
Ali の内部データ オブジェクト ヘッダーは 2 つの部分で構成されており、最初の部分にはオブジェクト自体の実行時データ (ハッシュ コード、 GC 生成経過時間、ロック識別ステータス、
スレッドが保持するロックは、スレッド ID (通常は 32/64 ビットを占有 ) に偏っています。2 番目の部分はポインタ型で、オブジェクトのクラス メタデータ型を指します。
(つまり、オブジェクトがどのクラスを表すか)。配列オブジェクトの場合、オブジェクト ヘッダーの別の部分を使用して配列の長さを記録します。
インスタンス データは、オブジェクトの実際の有効な情報 (親クラスから継承されたものや独自に定義されたものを含む) を格納するために使用されます。
アライメント パディング: JVM では、 オブジェクトの開始アドレスが 8バイト の整数倍である必要があります ( 8 バイト アライメント)。
14. リサイクル可能かどうかはどうやって判断するのですか?
オブジェクトが生きているかどうかを判断するには、通常、次の 2 つの方法があります。
参照カウント: 各オブジェクトには参照カウント属性があり、参照が追加されるとカウントが1 増加し、 参照が解放されるとカウントが 1減少します
数値が 0の場合 、リサイクルできます。この方法は単純ですが、オブジェクト間の循環参照の問題を解決できません。
可达性分析( Reachability Analysis ):从 GC Roots 开始向下搜索,搜索所走过的路径称为引
用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的,不可达对
象。
15 JVM 的永久代中会发生垃圾回收么?
垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收 (Full
GC) 。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确
的永久代大小对避免 Full GC 是非常重要的原因。请参考下 Java8 :从永久代到元数据区 ( 注: Java8
中已经移除了永久代,新加了一个叫做元数据区的 native 内存区 )
16 、你知道哪些垃圾收集算法
GC 最基础的算法有三种:
标记 - 清除算法、复制算法、标记 - 压缩算法,我们常用的垃圾回收器一般
都采用分代收集算法。
标记 - 清除算法,
标记 - 清除 Mark-Sweep )算法,如它的名字一样,算法分为 标记
两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。
复制算法,
复制 Copying )的收集算法,它将可用内存按容量划分为大小相等的两块,每次
只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后
再把已使用过的内存空间一次清理掉。
标记 - 压缩算法,标记过程仍然与 标记 - 清除 算法一样,但后续步骤不是直接对可回收对象进行
清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
分代收集算法,
分代收集 Generational Collection )算法,把 Java 堆分为新生代和老年代,
这样就可以根据各个年代的特点采用最适当的收集算法。
17 、调优命令有哪些?
Sun JDK の 監視および障害処理コマンドには、 jps jstat jmap jhat jstack jinfoが含まれます
Ali の内部データ jps ( JVM プロセス ステータス ツール) は、 指定されたシステム内の すべての HotSpot仮想マシン プロセスを表示します。
jstat JVM 統計監視は、 仮想マシンの実行状態情報を監視するために使用されるコマンドであり、仮想マシンの実行状態を表示できます。
マシン プロセスでのクラス ロード、メモリ、ガベージ コレクション、 JIT コンパイルなどの実行データ。
jmap JVM メモリ マップコマンドは ヒープ ダンプファイル の生成に使用されます
jhat : JVM ヒープ分析ツールコマンドは、 jmap と組み合わせて使用​​され jmapによって生成されたダンプをjhat内で分析します。
小さな HTTP/HTML サーバーをセットアップし、 ダンプ 分析結果を生成した後、ブラウザーで表示できます。
jstack 、現時点での Java仮想マシン のスレッド スナップショットを生成するために使用されます。
jinfo JVM Confifiguration info 这个命令作用是实时查看和调整虚拟机运行参数。
18 、常见调优工具有哪些
常用调优工具分为两类 ,jdk 自带监控工具: jconsole jvisualvm ,第三方有: MAT(Memory
Analyzer Tool) GChisto
jconsole Java Monitoring and Management Console 是从 java5 开始,在 JDK 中自带的 java
控和管理控制台,用于对 JVM 中内存,线程和类等的监控
jvisualvm jdk 自带全能工具,可以分析内存快照、线程快照;监控内存变化、 GC 变化等。
MAT Memory Analyzer Tool ,一个基于 Eclipse 的内存分析工具,是一个快速、功能丰富的
Java ヒープ 分析ツール。メモリ リークを発見し、メモリ消費量を削減するのに役立ちます。
GChisto 、 GCログを 専門的に分析するツール
19. マイナー GCフル GC はそれぞれ いつ 発生しますか?
新しい世代のメモリが十分でない場合、 MGCは YGC とも呼ばれ JVM のメモリが十分でない場合、 FGCが発生します。
20. どのような JVM パフォーマンス チューニング パラメータを知っていますか? (簡単な答え)
ヒープメモリサイズを設定する
-Xmx : 最大ヒープ メモリ制限。
若い世代のサイズを設定します。新しい世代は小さすぎてはなりません。小さすぎると、多数のオブジェクトが古い世代に溢れてしまいます。
-XX:NewSize : 新しい世代のサイズ
-XX: NewRatio 新世代と旧世代の割合
-XX:SurvivorRatio : エデン空間と生存者空間の比率
ガベージ コレクターを設定します。若い世代 -XX:+UseParNewGC 古い世代 -XX:+UseConcMarkSoupGC
21. オブジェクトはヒープに割り当てる必要がありますか? 脱出分析テクニックについて学んだことがありますか?
「オブジェクトはヒープに割り当てる必要がありますか?」 必ずしもそうではありません。JVM 「エスケープ分析」 を通過し 、メソッドからエスケープできないオブジェクトはスタック上にあります。
分配。
内部情報アリ 「脱出解析とは?」
エスケープ分析は、 Javaプログラムにおける同期負荷とメモリ ヒープ割り当てのプレッシャーを効果的に軽減できるクロスファンクションです
グローバル データ フロー分析アルゴリズム。 Java ホットスポットコンパイラは 、エスケープ分析を通じて、 新しいオブジェクトへの参照の使用を分析できます。
このオブジェクトをヒープに割り当てるかどうかを決定するスコープ。
エスケープ解析とは、 ポインタのダイナミックレンジを解析する手法のことで、コンパイラ最適化原理のポインタ解析やシェイプ解析に関連します。変化するとき
数量 (またはオブジェクト) がメソッドに割り当てられた後、そのポインターはグローバルに返されたり参照されたりするため、他のメソッドや
スレッドによって参照されるこの現象は、ポインター (または参照) のエスケープ(Escape) と呼ばれます 平たく言えば、オブジェクトへのポインタが
複数のメソッドまたはスレッドによって参照された場合、このオブジェクトのポインタがエスケープされたと言います。
「脱出分析のメリット」
スタックに割り当てることで、ガベージ コレクターの動作頻度を減らすことができます。
同期の排除。オブジェクトが 1 つのスレッドからのみアクセスできることが判明した場合、このオブジェクトに対する操作は同期なしで実行できます。
ステップ。
スカラー置換、オブジェクトの基本型への分解、およびメモリ割り当てはヒープではなくスタックに割り当てられます。
上長。この利点は次のとおりです。 1. オブジェクト ヘッダーを生成する必要がないため、メモリ使用量が削減されます。2. プログラムのメモリ回復効率が高く、
また、 GC 頻度も減少します。
22. 仮想マシンが永続世代ではなくメタスペースを使用するのはなぜですか?
「什么是元空间?什么是永久代?为什么用元空间代替永久代?」 我们先回顾一下 「方法区」 ,
看虚拟机运行时数据内存图,如下 :
阿里内部资料 方法区和堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、
静态变量、即时编译后的代码等数据。
「什么是永久代?它和方法区有什么关系呢?」
如果在 HotSpot 虚拟机上开发、部署,很多程序员都把方法区称作永久代。可以说方法区是规
范,永久代是 Hotspot 针对该规范进行的实现。在 Java7 及以前的版本,方法区都是永久代实现
的。
「什么是元空间?它和方法区有什么关系呢?」
对于 Java8 HotSpots 取消了永久代,取而代之的是元空间 (Metaspace) 。换句话说,就是方
法区还是在的,只是实现变了,从永久代变为元空间了。
「为什么使用元空间替换了永久代?」
永久代的方法区,和堆使用的物理内存是连续的。
阿里内部资料 「永久代」 是通过以下这两个参数配置大小的 ~
-XX:PremSize :设置永久代的初始大小
-XX:MaxPermSize: 设置永久代的最大值,默认是 64M
「永続世代」 の場合 、多くの クラスが動的に生成される場合、 java.lang.OutOfMemoryError:」 が発生する可能性があります。
PermGen スペース エラー」 。永続世代スペースの構成が制限されているためです。最も典型的なシナリオは、 Web開発に多数の JSPページ があることです。
フェイスタイム。
JDK8以降 、メソッド領域はメタスペース (Metaspace)内に存在します 物理メモリはヒープと連続していませんが、ローカルに直接存在します。
メモリ内では、理論的にはマシンは 「メモリと同じくらい、メタスペースと同じくらい」です
Ali 内部データは、 次のパラメータを通じてメタスペースのサイズを設定できます。
-XX:MetaspaceSize 、初期スペース サイズ。この値に達すると、型のアンロードと GCのためにガベージ コレクションがトリガーされます。
この値は調整されます。大量のスペースが解放されると、値は適切に減らされます。解放されるスペースが非常に少ない場合は、
MaxMetaspaceSize を 超えない場合は、値を適切に増やします
-XX:MaxMetaspaceSize 、最大スペース、デフォルトは無制限です。
-XX:MinMetaspaceFreeRatio GC後、 メタスペースの 最小残りスペース容量の割合
スペース割り当てのためのガベージ コレクションを削減する
-XX:MaxMetaspaceFreeRatio ,在 GC 之后,最大的 Metaspace 剩余空间容量的百分比,
减少为释放空间所导致的垃圾收集
「所以,为什么使用元空间替换永久代?」
表面上看是为了避免 OOM 异常。因为通常使用 PermSize MaxPermSize 设置永久代的大小就
决定了永久代的上限,但是不是总能知道应该设置为多大合适 , 如果使用默认值很容易遇到
OOM 错误。当使用元空间时,可以加载多少类的元数据就不再由 MaxPermSize 控制 , 而由系统
的实际可用空间来控制啦。
23 、什么是 Stop The World ? 什么是 OopMap ?什么是安全
点?
阿里内部资料 进行垃圾回收的过程中,会涉及对象的移动。为了保证对象引用更新的正确性,必须暂停所有的用
户线程,像这样的停顿,虚拟机设计者形象描述为 Stop The World 。也简称为 STW
HotSpot 中,有个数据结构(映射表)称为 OopMap 。一旦类加载动作完成的时候,
HotSpot 就会把对象内什么偏移量上是什么类型的数据计算出来,记录到 OopMap 。在即时编译过
程中,也会在 「特定的位置」 生成 OopMap ,记录下栈上和寄存器里哪些位置是引用。
这些特定的位置主要在:
1. 循环的末尾(非 counted 循环)
2. 方法临返回前 / 调用方法的 call 指令后
3. 可能抛异常的位置
这些位置就叫作 「安全点 (safepoint) 。」 用户程序执行时并非在代码指令流的任意位置都能够在
停顿下来开始垃圾收集,而是必须是执行到安全点才能够暂停。
24 、说一下 JVM 的主要组成部分及其作用?
JVM 包含两个子系统和两个组件,分别为
Class loader( 类装载子系统 )
実行エンジン ( 実行エンジン サブシステム )
実行時データ領域 ( 実行時データ領域コンポーネント )
ネイティブ インターフェイス ( ローカル インターフェイス コンポーネント )
クラスローダー ( クラスローディング ) :」 指定された完全修飾クラス名(例: java.lang.Object) に従って クラスファイルをロードします
ランタイムデータ領域のメソッド領域に。
Aliの内部データ 実行エンジン (実行エンジン)」 クラス の命令を実行します。
ネイティブ インターフェイス ( ローカル インターフェイス ) 」: ネイティブ ライブラリ と対話し 、他のプログラミング言語が対話するためのインターフェイスです。
実行時データ領域( 実行時データ領域 :これは、よく言われる JVMのメモリのことです
まず、 Javaソース コードは コンパイラによって バイトコードに変換され、 クラス ローダ ( クラス ローディング ) によってバイトコードがメモリにロードされます。
、ランタイムデータ領域のメソッド領域に置きます。バイトコードファイルは JVMの命令セット仕様のセットにすぎず 、直接実行することはできません。
実行のために基礎となるオペレーティング システムに渡されるため、特定のコマンド パーサー実行エンジン ( 実行エンジン ) が必要です。
バイトコードは基盤となるシステム命令に変換され、 CPU に渡されて 実行されますが、このプロセスでは他の言語のローカル ライブラリを呼び出す必要があります。
プログラム全体の機能を実現するためのインターフェース( ネイティブインターフェース)。
25. ポインタ衝突とは何ですか?
一般に、 JVM オブジェクトはヒープ メモリに配置されます (エスケープ分析を除く)。クラス読み込みチェックに合格すると、 Java 仮想
マシンは、新しく生まれたオブジェクトにメモリの割り当てを開始します。 Javaヒープ内のメモリが完全に規則的で ある場合 、使用されるすべてのメモリは 1 つのヒープに配置されます。
一方の側には空きメモリがもう一方の側に配置され、境界点を示すポインタが中央に配置されます。割り当てられたメモリは、
ポインタは、オブジェクトのサイズに等しいインスタンスの空き領域の方向に移動します。この割り当て方法は、ポインタ衝突です。
26. フリーリストとは何ですか?
Javaヒープメモリ内のメモリが規則的でない 場合 、使用メモリと空きメモリが交互に配置され、
ライン ポインタが衝突すると、仮想マシンは使用可能なメモリを記録するリストを維持し、割り当てるときにリストからブロックを見つける必要があります。
オブジェクトインスタンスに大きな領域を割り当て、リスト上のレコードを更新する割り当て方法がフリーリストです。
27. TLAB とは何ですか ?
メモリ割り当てのアクションはスレッドに応じて異なる領域に分割でき、各スレッドは Javaヒープ内の 小さなブロックを事前に割り当てます。
メモリ 、これは TLAB (スレッド ローカル割り当てバッファ、ローカル スレッド割り当てキャッシュ) です。
仮想マシンは合格します -
XX:UseTLAB で設定します。
28. オブジェクトヘッダーには具体的にどのような内容が含まれますか?
一般的に使用されている ホットスポット 仮想マシンでは、メモリ内のオブジェクトのレイアウトには実際に 3 つの 部分が含まれています。
1. オブジェクトヘッダー
Aliの内部情報 2. インスタンスデータ
3. パディングを揃える
オブジェクトヘッダーには 2 つの部分が含まれており、 Mark Word の内容はロックフラグによって変更されるため、ストレージ構造のみが変更されます。
大丈夫。
1. 実行時にオブジェクト自体が必要とするデータ ( Mark Wordとも呼ばれます) は 、軽量ロックとバイアスされたロックのキー ポイントです。
特定のコンテンツには、オブジェクトの ハッシュコード 、世代年齢、軽量ロック ポインター、重量ロック ポインター、 GC マーク、バイアスが含まれます。
ロック スレッド ID 、バイアス ロック タイムスタンプ。
2. ストレージ タイプ ポインタ、つまりクラスのメタデータへのポインタを使用して、オブジェクトがどのクラスに属しているかを判断できます。
例。
配列の場合は、配列の長さも含まれます。
29. どのような JVM チューニング パラメータを知っていますか?
「スタックメモリ関連」
-Xms は 初期ヒープ サイズを設定します
-Xmx は 最大ヒープ サイズを設定します
-Xmn は、 若い世代のサイズを設定します。これは、 -XX:NewSize -XX:MaxNewSize を 同時に同じ値に構成するのと同等です。
-Xss スレッドあたりのスタック サイズ
-XX:NewSize は 若い世代のサイズを設定します (1.3/1.4 の場合)
-XX:MaxNewSize 若い世代の最大値 (1.3/1.4の場合)
-XX: NewRatio 古い世代に対する若い世代の比率 永続世代を除く
-XX:SurvivorRatioエデン エリアと サバイバーエリア の比率
-XX:PretenureSizeThreshold 作成したオブジェクトが指定サイズを超えた場合、旧世代のオブジェクトを直接割り当てます。
-XX:MaxTenuringThreshold は、 Survivorにコピーされたオブジェクトの最大存続期間のしきい値 を設定します。しきい値を超えると、 Survivor に転送されます。
古い世代
内部情報アリ 「ガベージコレクター関連」
-XX:+UseParallelGC : ガベージ コレクターを並列コレクターとして選択します。
-XX:ParallelGCThreads=20 : 並列コレクターのスレッド数を構成します。
-XX:+UseConcMarkSweatGC : 同時収集用に古い世代を設定します。
-XX:CMSFullGCsBeforeCompaction=5 コンカレント コレクターはメモリ空間を圧縮して整理しないため、
そのため、一定時間稼働すると 断片化 」が発生し 、作業効率が低下します。この値は、 GC後に 5 回実行されるように設定されています。
収納スペースが圧縮されて整理整頓されます。
-XX:+UseCMSCompactAtFullCollection : 古い世代の圧縮をオンにします。パフォーマンスに影響するかもしれませんが、
ゴミを除去できる
「補助情報関連」
-XX:+PrintGCDetails GC の詳細を 印刷します。
-XX:+HeapDumpOnOutOfMemoryError を使用すると、メモリ オーバーフローが発生したときに JVMがメモリ スナップショットを自動的に生成でき ます
トラブルシューティング
-XX:+DisableExplicitGC は、 誤ってFGC を手動でトリガーすることによって引き起こされる問題を防ぐために 、システム System.gc()を禁止します
-XX:+PrintTLAB TLABスペースの使用状況 を表示する
30. JVMにはどのような種類のガベージ コレクターがあるのか ​​教えてください。
ガベージ コレクション アルゴリズムがメモリ回復の方法論である場合、ガベージ コレクタはメモリ回復の特定の実装です。以下の図は、
異なる世代に作用する7 種類のコレクター。そのうち、新しい世代のリサイクルに使用されるコレクターには Serial PraNew Parallelが含まれます。
Scavenge 、古い時代を再利用するためのコレクターには Serial Old Parallel Old CMSが含まれ、 Javaヒープ 全体を再利用するための
G1 コレクター。異なるコレクター間の線は、それらが一緒に使用できることを示しています。
阿里内部资料 Serial 收集器(复制算法 ): 新生代单线程收集器,标记和清理都是单线程,优点是简单高效;
ParNew 收集器 ( 复制算法 ): 新生代收并行集器,实际上是 Serial 收集器的多线程版本,在多核
CPU 环境下有着比 Serial 更好的表现;
Parallel Scavenge 收集器 ( 复制算法 ): 新生代并行收集器,追求高吞吐量,高效利用 CPU 。吞
吐量 = 用户线程时间 /( 用户线程时间 +GC 线程时间 ) ,高吞吐量可以高效率的利用 CPU 时间,尽
快完成程序的运算任务,适合后台应用等对交互相应要求不高的场景;
Serial Old 收集器 ( 标记 - 整理算法 ): 老年代单线程收集器, Serial 收集器的老年代版本;
パラレル オールド コレクター ( マーク 照合 アルゴリズム ) :
旧世代のパラレル コレクター、スループット優先、 パラレル スカベンジ コレクション
コレクターの旧世代バージョン。
CMS (同時マーク スイープ) コレクター (マーク - クリア アルゴリズム):
最短距離を取得するための旧世代のパラレル コレクター
収集の一時停止時間を目的としたコレクターは、高い同時実行性と低い一時停止の特性を備えており、最短の GC 収集一時停止時間を追求します。
G1 (Garbage First) コレクター ( マーク - ソート アルゴリズム ) : Java ヒープ並列コレクター、 G1 コレクターは JDK1.7 によって提供されます。
新しいコレクターである G1コレクターは、 mark - compact 」アルゴリズム に基づいて実装されており 、メモリの断片化を生成しません。さらにG1は集めます
以前のコレクターと異なるコレクターの重要な機能は次のとおりです。 G1リサイクルの範囲は、 Javaヒープ 全体 (新世代、古い世代を含む)です。
最初の 6 つのコレクターの 範囲は、新しい世代または古い世代に限定されます
ZGC ( Z Garbage Collector ) は、 Oracle Corporation によって開発されたガベージ コレクターであり 、低遅延を主な目標としています。
コレクタ。これは動的な リージョン メモリ レイアウトに基づいており、(一時的に)エイジ ジェネレーションを設定せず、読み取りバリア、カラー ポインタ、およびメモリを使用します。
メモリ マルチマッピングなどの技術を使用した同時マーク -コンパクト アルゴリズムを実装する コレクター。 JDK 11 新たに追加されましたが、まだ実験段階です
セグメントの主な機能は、 TB レベルのメモリ (最大 4T ) の回復、一時停止時間は 10msを超えません 利点 : 低停止、高スループット
ZGC収集プロセス 中に消費される追加メモリの 量は少量です。 デメリット :ゴミが浮いてしまう
現在はほとんど使用されておらず、実際に普及するには作成に時間がかかるでしょう。
新世代コレクター : シリアル パーニュー パラレル スカベンジ
古い時代のコレクター : CMS シリアルオールド パラレルオールド
ヒープ全体コレクター : G1 ZGC ( 古いため図にはありません )
31. ガベージコレクターの選び方は?
1.ヒープ サイズがそれほど大きくない場合 ( 100MB など )、通常はシリアル コレクターを選択するのが最も効率的です。
パラメータ: -XX :+UseSerialGC
2. アプリケーションがシングルコア マシンで実行されている場合、または仮想マシンにシングル コアしかない場合でも、シリアル コレクタを選択することが適切です。
現時点では、一部の並列コレクターを有効にしてもメリットはありません。
パラメータ: -XX :+UseSerialGC
3. アプリケーションが スループット 優先であり、より長い一時停止に対する特別な要件がない場合。並列コレクションを選択します
デバイスの方が良いです。
パラメータ: -XX :+UseParallelGC
Ali 内部情報 4. アプリケーションの応答時間に高い要件がある場合、一時停止を減らす必要があります。 1秒の一時停止 でも、 多くのリクエストが失敗する可能性があります
失敗した場合は、 G1 ZGC 、および CMSを選択するの が合理的です。これらのコレクターの GC一時停止は 通常短いですが、
これらのジョブを処理するには追加のリソースが必要ですが、通常はスループットが低くなります。
パラメータ:
- XX:+UseConcMarkSoupGC
- XX:+UseG1GC
-XX :+ZGC などを使用します。
上記の出発点から、通常の Web サーバーには応答性に対する非常に高い要件があります。選択度は実際に設定されます
CMS G1 ZGC の媒体 一部のタイミング タスクでは、並列コレクターを使用する方が適切な選択です。
32. クラスローダーとは何ですか?
クラスローダーは、クラスファイルをロードするために使用されるクラスです。 Java ソース コードは、 javac コンパイラによってクラス ファイルにコンパイルされます。その後、 JVM が実行されます。
プログラムを実行するための行クラス ファイル内のバイトコード。クラス ローダーは、ファイル システム、ネットワーク、またはその他のソースからクラス ファイルをロードする役割を果たします。
33. Tomcatクラスロードメカニズム とは何ですか ?
以下に示すように、 Tomcat でのクラスのロード は少し異なります。
Ali の内部情報 Tomcatが起動する 、いくつかのクラス ローダーが作成されます。
Bootstrap ブートストラップ クラス ローダー は、 JVM の起動 に必要なクラスをロードします。
標準拡張クラス ( jre/lib/extにあります )
システム システム クラス ローダーは tomcat によって開始されたクラスをロードします。
bootstrap.jar 。通常は catalina.batまたはcatalina.sh で指定されます CATALINA_HOME/binの下にあります
共通汎用 クラスローダ
WeChat パブリック アカウントにご注目ください: Java バックエンド テクノロジのフルスタック
マルチスレッド 同時実行
1. Javaでマルチスレッドを実装するいくつかの方法 について話す
スレッドを作成するには、次の 3 つの一般的な方法があります。
1. Threadクラス を継承する
2. Runnableインターフェイス を実装する
3. Callableインターフェース を実装する ( JDK1.5>= )
4. スレッドプールの作成
マルチスレッドは、 Thread クラス を継承するか、 Runnable インターフェースと Callableインターフェースを実装することで実現できますが、 Runnableを実装する必要があります。
このインターフェイスは基本的にCallableインターフェイスの 実装と同じです が、 Callableインターフェイス で定義されたメソッドの戻り値が例外をスローするように宣言できる点が異なります。
いつもの。 したがって、 Runnableインターフェース の実装とCallableインターフェース の実装は 1 つのメソッドに分類されます。この方法はThreadを継承する方法と似ています。
両者の主な違いは以下の通りです。
Runnable インターフェイス Callableインターフェイス を実装してスレッドを作成する利点と欠点
利点 : スレッド クラスは Runnable または Callable インターフェイスのみを実装し、他のクラスも継承できます。このようにして、複数のスレッド
ターゲットオブジェクトは共有できるため、複数の同一スレッド 同じリソースを処理するのに非常に適しています。
CPU 、コード、データが分離されて明確なモデルが形成され、オブジェクト指向の考え方がよりよく反映されます。
短所 : プログラミングは少し複雑です。現在のスレッドにアクセスする必要がある場合は、 Thread.currentThread() メソッドを使用する必要があります。
Thread クラスを継承してスレッドを作成するメリットとデメリット
Ali の内部データ の利点 : 書き込みが簡単、現在のスレッドにアクセスする必要がある場合、 Thread.currentThread()メソッド を使用する必要はなく 、直接使用するだけです。
これは 現在のスレッドを取得します
欠点 :スレッドクラスは Thread クラスを継承しているため、 Java 言語は単一継承なので、他の親クラスを継承できません。
2. 実行中のスレッドを停止する方法
1. 終了フラグを使用して、スレッドを正常に終了します。つまり、 run メソッドが完了するとスレッドが終了します。
2. stopメソッドを 使用して強制終了しますが、 stop suspend resumeはいずれも期限切れの操作であるため、この方法はお勧めできません。
無駄な方法。
3. スレッドを中断するには、interruptメソッド を使用します。
class MyThread extends Thread {
揮発性ブール値 stop = false;
public void run() {
while (!stop) {
System.out.println(getName() + " が実行中です");
試す {
睡眠(1000);
} catch (InterruptedException e) {
System.out.println("ブロックから一週間後...");
stop = true; // 例外処理コード内の共有変数の状態を変更します
}
}
System.out.println(getName() + " 終了しています...");
}
}
クラスInterruptThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
MyThread m1 = 新しい MyThread();
System.out.println("スレッドを開始しています...");
m1.start();
Thread.sleep(3000);
System.out.println("スレッドを中断します...: " + m1.getName());
m1.stop = true; // 共有変数を trueに設定します
m1.interrupt(); // ブロックされた場合はブロック状態を終了する
Thread.sleep(3000); // 主线程休眠 3 秒以便观察线程 m1 的中断情况
System.out.println("Stopping application...");
}
}
阿里内部资料 3 notify() notifyAll() 有什么区别?
notify 可能会导致死锁,而 notifyAll 则不会
任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行 synchronized 中的代码
使用 notifyall, 可以唤醒 所有处于 wait 状态的线程,使其重新进入锁的争夺队列中,而 notify 只能唤
醒一个。
wait() 应配合 while 循环使用,不应使用 if ,务必在 wait() 调用前后都检查条件,如果不满足,必须调
notify() 唤醒另外的线程来处理,自己继续 wait() 直至条件满足再往下执行。
Notice()は NoticeAll()を最適化し たものです が、非常に正確なアプリケーション シナリオがあり、正しく使用する必要があります。そうしないと、原因となる可能性があります
行き詰まり。正しいシナリオは、 WaitSetの待機条件 が同じであり、どれでもウェイクアップすると次の処理を正しく処理できることです。
項目で、目覚めたスレッドを正しく処理できない場合は、必ず次のスレッドで notification()を続行し 、 に戻る必要があります。
待機 セット ._
4. sleep () wait() の違いは何ですか?
sleep()メソッド については、まずこのメソッドがThreadクラス に属していることを知る必要があります wait ()メソッドはObjectクラスに属します
中的。
sleep()メソッドにより、プログラムは指定された時間実行を一時停止し、 CPU を他のスレッドに 放棄します が、監視ステータスは維持されます。
または、指定した時間が経過すると、自動的に実行状態が再開されます。 sleep()メソッド を呼び出すプロセスでは 、スレッドはオブジェクトを解放しません。
ロック。
wait()メソッド が呼び出されると 、スレッドはオブジェクト ロックを放棄し、このオブジェクトを待機する待機ロック プールに入ります。
Notice() メソッドの後、スレッドはオブジェクト ロック プールの準備に入り、オブジェクト ロックを取得して実行状態に入ります。
5. 揮発性とは何ですか?順序は保証 されますか ?
共有変数 (クラス メンバー変数、クラス スタティック メンバー変数) が volatileによって変更される と、2 つの言語層が形成されます。
義人:
1 ) この変数を操作するさまざまなスレッドの可視性を保証します。つまり、スレッドは変数の値を変更し、新しい値は
他のスレッドからすぐに見えるように 、 volatile キーワードを使用すると、変更された値が直ちにメイン メモリに書き込まれます。
2 ) 命令の並べ替えを無効にします。
volatile は アトミック操作ではありません
保証された半順序とは何ですか ?
プログラムが volatile 変数への読み取り操作または書き込み操作を実行するときは、前の操作の変更が実行されている必要があり、その結果は
後続の操作に対してすでに表示されている場合は、後続の操作をまだ実行してはいけません。
Ali 内部データ x = 2; // ステートメント 1
y = 0; // ステートメント 2
flag = true; // ステートメント 3
x = 4; // ステートメント 4
y = -1; // ステートメント 5
flflag 変数は 揮発性変数で あるため、ステートメント3はステートメント1 、ステートメントには配置 されません。
2の前に、ステートメント 3をステートメント4およびステートメント5の後ろに 置くことはできません ただし、ステートメント1とステートメント2 、ステートメント4とステートメント5の順序に注意してください。
順序は保証されません。
volatile の使用は 通常、状態マーカーとシングルトン モードでの二重チェックされたロックに使用されます。
6. Threadクラスstart() メソッドrun()メソッドの違いは何 ですか ?
start() メソッドは新しく作成されたスレッドを開始するために使用され、 start() は内部的に run()メソッド を呼び出します。これは run()メソッドを直接呼び出すのと同じです。
効果は異なります。 run()メソッド を呼び出すと 、元のスレッドでのみ呼び出され、新しいスレッドは開始されません
新しいスレッドを開始するメソッド。
7. wait、notify notifyAll がスレッドクラスにない 理由
麺?
明らかな理由は、 JAVA によって提供されるロックがスレッド レベルではなくオブジェクト レベルであるためであり、各オブジェクトにはロックがあり、スレッドを通じて取得されます。ラインの場合
プログラムが何らかのロックを待機する必要がある場合は、オブジェクトに対して wait()メソッドを呼び出す のが合理的です。 wait()メソッドが Threadクラス で定義されている 場合、次の行
プログラムがどのロックを待っているかは明らかではありません。簡単に言うと、 wait Notice 、および NoticeAll は ロックレベルの操作であるため、
ロックはオブジェクトに属しているため、 Objectクラス で定義できます
8. 待機メソッド通知メソッドを同期ブロックで呼び出す必要があるのは なぜですか?
1. オブジェクトの wait()、notify()、およびNoticeAll()メソッドは、 呼び出しスレッドがオブジェクトに対して排他ロックを持っている場合にのみ呼び出すことができます。
法。
2. これを行わないと、コードは IllegalMonitorStateExceptionをスローします
3. 还有一个原因是为了避免 wait notify 之间产生竞态条件。
wait() 方法强制当前线程释放对象锁。这意味着在调用某对象的 wait() 方法之前,当前线程必须已经
获得该对象的锁。因此,线程必须在某个对象的同步方法或同步代码块中才能调用该对象的 wait()
法。
在调用对象的 notify() notifyAll() 方法之前,调用线程必须已经得到该对象的锁。因此,必须在某
个对象的同步方法或同步代码块中才能调用该对象的 notify() notifyAll() 方法。
调用 wait() 方法的原因通常是,调用线程希望某个特殊的状态 ( 或变量 ) 被设置之后再继续执行。调用
notify() notifyAll() 方法的原因通常是,调用线程希望告诉其他等待中的线程 :" 特殊状态已经被设
「 」 を設定します 。この状態はスレッド間通信のチャネルとして機能し、変更可能な共有状態 ( または変数 )である必要があります
Alibaba 内部情報 9. Java中断メソッドisInterruptedメソッド の違いは何ですか?
interrupted() isInterrupted()の主な違い は、前者は割り込みステータスをクリアするのに対し、後者はクリアしないことです。 Java マルチスレッド
割り込みメカニズムは内部フラグで実装されており、 Thread.interrupt()を呼び出して スレッドを割り込むと、割り込みフラグが trueに設定されます
割り込みが発生したスレッドが静的メソッド Thread.interrupted()を呼び出して 割り込みステータスを確認すると、割り込みステータスはクリアされます。静的ではなく
isInterrupted() メソッドは、 割り込みステータス フラグを変更せずに、他のスレッドの割り込みステータスをクエリするために使用されます。簡単に言えば、どんな投げでも
InterruptedException メソッドは割り込みステータスをクリアします。ただし、スレッドの中断状態によって、
割り込みは、変更するために他のスレッドによって呼び出されます。
10. JavaにおけるsynchronizedLockReentrantLockの違いは 何ですか ?
類似性:
これら 2 つの同期方法には多くの類似点があり、どちらも同期をロックするものと同期をブロックするものです。
スレッドがオブジェクト ロックを取得して同期ブロックに入った場合、同期ブロックにアクセスする他のスレッドは同期ブロックの外側でブロックされる必要があります。
待機中、スレッドのブロックとウェイクアップのコストは比較的高くなります
違い:
これら 2 つのメソッドの最大の違いは、 Synchronized の場合 、これが Java 言語のキーワードであり、ネイティブ構文レベルでの対話であることです。
拒否には jvm の 実装が必要です。ReentrantLock JDK 1.5以降に提供されるAPIレベルのミューテックス であり、 lock()
lock()メソッドは、 try/fifinallyステートメント ブロック と連携して 完了します。
Synchronizedがコンパイルされ、 同期ブロックの前後に 2 つのバイトコード 、monitorenter monitorexitが形成されます。
命令。 monitorenterコマンド を実行するときは 、まずオブジェクトロックの取得を試みます。オブジェクトがロックされていない場合、または現在の行がロックされていない場合
プログラムが既にオブジェクト ロックを所有している場合は、ロックのカウンタに 1を加えます 。これに応じて、 monitorexit 命令が実行されると、ロックのカウンタは次のようになります。
1 を減算し 、カウンタが 0に達する とロックが解除されます。オブジェクト ロックの取得に失敗した場合、現在のスレッドはオブジェクト ロックが取得されるまでブロックされます。
別のスレッドが解放されるまで。
ReentrantLock は java.util.concurrentパッケージで提供されるミューテックスのセット あるため、 Synchronizedと比較すると
ReentrantLock クラスは、主に次の 3 つの 項目を含むいくつかの高度な機能を提供します。
1. 待機を中断することができます。ロックを保持しているスレッドが長時間解放されない場合、待機中のスレッドは待機を放棄することを選択できます。
同期することで デッドロックを回避できます。
2. 公平なロック: 複数のスレッドが同じロックを待機している場合、それらは適用された順序でロックを取得する必要があります。 同期された ロックは公平ではありません。
ReentrantLock のデフォルトのコンストラクターである Lockは、不公平なロックを作成します。これは、パラメーター trueを使用して公平なロックとして設定できます が、公平なロックは
パフォーマンスはあまり良くありません。
3. ロックは複数の条件にバインドされており、 ReentrantLock オブジェクトは同時に 2 つのオブジェクトにバインドできます。
11 、有三个线程 T1,T2,T3, 如何保证顺序执行?
阿里内部资料 在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的 join() 方法在一个线程中启动另一
个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个 (T3
T2 T2 调用 T1) ,这样 T1 就会先完成而 T3 最后完成。
实际上先启动三个线程中哪一个都行,
因为在每个线程的 run 方法中用 join 方法限定了三个线程的
执行顺序。
public class JoinTest2 {
// 1. 现在有 T1 T2 T3 三个线程,你怎样保证 T2 T1 执行完后执行, T3 T2 执行完后执行
public static void main(String[] args) {
final Thread t1 = new Thread(new Runnable() {
@オーバーライド
public void run() {
System.out.println("t1");
}
});
最終スレッド t2 = 新しいスレッド(new Runnable() {
@オーバーライド
public void run() {
試す {
// t1スレッド を参照し t1スレッドの実行が完了するまで待ちます
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2");
}
});
スレッド t3 = 新しいスレッド(新しい Runnable() {
@オーバーライド
public void run() {
試す {
// t2スレッド を参照し t2スレッドの実行が完了するまで待ちます
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t3");
}
アリの内部情報 });
t3.start();// ここでの 3 つのスレッドの開始順序は任意であり、試してみることができます。
t2.start();
t1.start();
}
}
12. SynchronizedMapConcurrentHashMapの違いは 何ですか ?
SynchronizedMap() は、 Hashtable と同様に、 マップのすべてのメソッドを呼び出すときにマップ全体を同期します
ConcurrentHashMapの実装は より 洗練されており、 マップ 内のすべてのバケットをロックします。したがって、スレッドがある限り、
マップ にアクセスする と、他のスレッドは マップに入ることができなくなり 、スレッドが ConcurrentHashMap のバケットにアクセスすると、そのスレッドは
他のスレッドは引き続き マップ上で 特定の操作を実行できます。
したがって、 ConcurrentHashMap は、 パフォーマンスとセキュリティの点で Collections.synchronizedMap()よりも明らかに 効率的です。
利点があります。同時に、同期操作はバケットに対して正確に制御されるため、 マップを 走査しているときでも 、他のスレッドが同期 操作を試みた場合でも、
データを変更してもConcurrentModifificationException はスローされません
13. スレッドセーフとは何ですか
スレッド セーフとは、複数のスレッドが同じコード部分にアクセスしても不確実な結果が生成されないことを意味します。
これも理論的な質問であり、さまざまな答えがありますが、私が個人的に最もよく説明していると思う答えを 1 つ挙げます。
マルチスレッドで実行した場合とシングル スレッドで実行した場合で常に同じ結果が得られる場合、コードはスレッド セーフです
この問題については言及する価値があります。つまり、スレッド セーフにはいくつかのレベルがあるということです。
( 1 ) 不変
String Integer Long と 同様 、これらは fifinal 型であり、どのスレッドもそれらの値を変更できません。
新規作成ではないため、これらの不変オブジェクトは同期手段なしでマルチスレッド環境で直接使用できます。
( 2 ) 絶対的なスレッドセーフ
実行時環境に関係なく、呼び出し元は追加の同期手段を必要としません。これを行うには通常、多くの追加のものが必要になります
Javaでは、自らをスレッドセーフとしてマークするクラスの 代償 として、実際、それらのほとんどはスレッドセーフではありませんが、完全にスレッドセーフです。
Javaには、 CopyOnWriteArrayListCopyOnWriteArraySet などの クラスもあります。
( 3 ) 比較的スレッドセーフ
相対的なスレッド セーフティは、通常スレッド セーフティと呼ばれるものです。 Vectorと同様に 追加メソッド 削除 メソッドはアトミックです
操作は中断されませんが、スレッドが Vector をトラバースし 同時に これを 追加している場合に制限されます。
Vector 99% 的情况下都会出现 ConcurrentModifificationException ,也就是 fail-fast 机制
4 )线程非安全
这个就没什么好说的了, ArrayList LinkedList HashMap 等都是线程非安全的类
阿里内部资料 14 Thread 类中的 yield 方法有什么作用?
Yield 方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行。它是一个静态方法
而且只保证当前线程放弃 CPU 占用而不能保证使其它线程一定能占用 CPU ,执行 yield() 的线程有可
能在进入到暂停状态后马上又被执行。
15 Java 线程池中 submit() execute() 方法有什么区别?
どちらのメソッドもスレッド プールにタスクを送信できます 。execute()メソッド の戻り値の型は Executorインターフェイスで定義されている voidです
submit ()メソッドは 、計算結果を保持する Futureオブジェクトを返すことができます。これは、 ExecutorServiceインターフェイス で定義されており、
Executorインターフェイス、 ThreadPoolExecutorScheduledThreadPoolExecutor などの他のスレッド プール クラスには これらがあります。
方法。
16. 同期キーワードについての理解 について話す
synchronized キーワードは、複数のスレッド間でのリソースへのアクセスの同期を解決します。また、 synchronized キーワードは、同期が確実に行われるようにすることができます。
装飾されたメソッドまたはコード ブロックは、常に 1 つのスレッドによってのみ実行できます。また、 以前のバージョンの Javaでは、
Synchronized は重量のあるロックであり、モニター ロック ( monitor ) が基盤となるオペレーティング システムに依存しているため非効率的です。
Mutex Lock が実装され、 Java スレッドがオペレーティング システムのネイティブ スレッドにマップされます。一時停止またはウェイクアップしたい場合は、
各スレッドが完了するにはオペレーティング システムの助けが必要で、スレッド間を切り替えるときにオペレーティング システムはユーザー モードからカーネルに切り替える必要があります。
状態の間の遷移には比較的長い時間がかかり、時間コストが比較的高いため、早期に
同期 効率が低い理由。 幸いなことに、 Java 6 以降、 Java関係者はJVMレベルからの同期についてより懸念を抱いています
優れた最適化により、 同期 ロックの効率も非常に適切に最適化されました。 JDK1.6 では、 ロックの実装に多くの利点が導入されています。
スピン ロック、適応スピン ロック、ロックの削除、ロックの粗化、バイアスされたロック、軽量ロックなどのテクノロジを使用して、ロック操作のオーバーヘッドを削減します。
17. synchronizedキーワード の使用方法を教えてください
変更されたインスタンス メソッド : 現在のオブジェクト インスタンスをロックするように動作し、同期コードに入る前に現在のオブジェクト インスタンスのロックを取得します。 変更された 静的メソッド:
つまり、静的メンバーはどのインスタンス オブジェクトにも属さず、クラスであるため、現在のクラスをロックすると、そのクラスのすべてのオブジェクト インスタンスに影響します。
Member ( staticは、これがこのクラスの静的リソースであることを示します。 新しいオブジェクトがいくつで あっても、コピーは 1 つだけ存在します)。 それで、もし
スレッド A はインスタンス オブジェクトの 非静的 同期メソッドを呼び出します。スレッド Bはインスタンス オブジェクトが属するクラスの静的同期メソッドを呼び出す必要があります。
状態 同期 メソッドは許可され、静的 同期メソッド へのアクセスが占有されるため、相互排他は発生しません。
ロックは現在のクラスのロックであり、非静的 同期メソッドへのアクセス によって占有されるロックは現在のインスタンス オブジェクト ロックです。変更されたコード ブロック : を指します
同期コード ベースに入る前に、ロック オブジェクトを指定し、指定されたオブジェクトをロックし、指定されたオブジェクトのロックを取得します。 概要 : 同期 オフ
静的 静的メソッドおよび 同期された (クラス) コード ブロック にキーワードを追加すると、 Class クラスがロックされます。 同期した
インスタンス メソッドに追加されたキーワードは、オブジェクト インスタンスをロックすることです。 JVMでは、 synchronized(String a) という単語が使用されない ように 注意してください。
文字列定数プールにはキャッシュ機能があります!
18. スレッドセーフとは何ですか? Vector はスレッドセーフなクラス ですか?
阿里内部资料 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每
次运行结果和单线程运行的结果是一样的,而且其他的变量 的值也和预期的是一样的,就是线程安
全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失
误。很显然你可以将集合类分 成两组,线程安全和非线程安全的。 Vector 是用同步方法来实现线程
安全的 , 而和它相似的 ArrayList 不是线程安全的。
19 volatile 关键字的作用?
一旦一个共享变量(类的成员变量、类的静态成员变量)被 volatile 修饰之后,那么就具备了两层语
义:
保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对
其他线程来说是立即可见的。
禁止进行指令重排序。
volatile 本质是在告诉 jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读
取; synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
volatile 仅能使用在变量级别; synchronized 则可以使用在变量、方法、和类级别的。
volatile 仅能实现变量的修改可见性,并不能保证原子性; synchronized 则可以保证变量的修改
可见性和原子性。
volatile 不会造成线程的阻塞; synchronized 可能会造成线程的阻塞。
volatile 标记的变量不会被编译器优化; synchronized 标记的变量可以被编译器优化。
20 、常用的线程池有哪些?
newSingleThreadExecutor :创建一个单线程的线程池,此线程池保证所有任务的执行顺序按
照任务的提交顺序执行。
newFixedThreadPool :创建固定大小的线程池,每次提交一个任务就创建一个线程,直到线
程达到线程池的最大大小。
newCachedThreadPool :创建一个可缓存的线程池,此线程池不会对线程池大小做限制,线
程池大小完全依赖于操作系统(或者说 JVM )能够创建的最大线程大小。
newScheduledThreadPool :创建一个大小无限的线程池,此线程池支持定时以及周期性执行
任务的需求。
newSingleThreadExecutor :创建一个单线程的线程池。此线程池支持定时以及周期性执行任
务的需求。
21 、简述一下你对线程池的理解
(このような質問をすると、スレッド プールの使用方法、スレッド プールの利点、スレッド プールの起動戦略について話すことができます)
スレッド プールを合理的に使用すると、3 つの利点が得られます。
まず、リソース消費を削減します。作成されたスレッドを再利用することで、スレッドの作成と破棄のコストを削減します。
Aliの内部情報 その2:応答速度の向上。タスクが到着すると、スレッドの作成を待たずにすぐにタスクを実行できます。
3 番目: スレッドの管理性を向上させます。スレッドは希少なリソースです。無制限に作成すると、システム リソースを消費するだけでなく、リソースの削減にもつながります。
システムの安定性は低いですが、スレッド プールを使用して、統合された割り当て、チューニング、監視を行うことができます。
22. Javaプログラムは どのように 実行されますか?
私たちは日常業務で、開発ツール ( IntelliJ IDEA Eclipse など) を使用してプログラムを非常に便利にデバッグしています。
パッケージ化ツールを使用してプロジェクトを jar パッケージまたは war パッケージにパッケージ化し、 Tomcat などの Webコンテナーに入れて 通常どおり実行します。
Javaプログラムが内部でどのように実行されるか 考えたことはありますか ? 実際、開発ツールで実行しているか Tomcatで 実行しているかに関係なく、
Java プログラムの実行の流れは基本的に同じで、実行の流れは次のとおりです。
まず、 Java コードをバイトコードにコンパイルします。つまり、 .java タイプ ファイルを .class タイプ ファイルにコンパイルします。このプロセス
的大致执行流程: Java 源代码 -> 词法分析器 -> 语法分析器 -> 语义分析器 -> 字符码生成器 ->
最终生成字节码,其中任何一个节点执行失败就会造成编译失败;
class 文件放置到 Java 虚拟机,这个虚拟机通常指的是 Oracle 官方自带的 Hotspot JVM
Java 虚拟机使用类加载器( Class Loader )装载 class 文件;
类加载完成之后,会进行字节码效验,字节码效验通过之后 JVM 解释器会把字节码翻译成机器
码交由操作系统执行。但不是所有代码都是解释执行的, JVM 对此做了优化,比如,以
Hotspot 虚拟机来说,它本身提供了 JIT Just In Time )也就是我们通常所说的动态编译器,
它能够在运行时将热点代码编译为机器码,这个时候字节码就变成了编译执行。 Java 程序执行
流程图如下:
阿里内部资料 23 、锁的优化机制了解吗?
JDK1.6 版本之后, synchronized 本身也在不断优化锁的机制,有些情况下他并不会是一个很重量
级的锁了。优化机制包括自适应锁、自旋锁、锁消除、锁粗化、轻量级锁和偏向锁。
锁的状态从低到高依次为 无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁 ,升级的过程就是从低到高,降级在
一定条件也是有可能发生的。
自旋锁 :由于大部分时候,锁被占用的时间很短,共享变量的锁定时间也很短,所有没有必要挂起
线程,用户态和内核态的来回上下文切换严重影响性能。自旋的概念就是让线程执行一个忙循环,
可以理解为就是啥也不干,防止从用户态转入内核态,自旋锁可以通过设置 -XX:+UseSpining 来开
启,自旋的默认次数是 10 次,可以使用 -XX:PreBlockSpin 设置。
自适应锁 :自适应锁就是自适应的自旋锁,自旋的时间不是固定时间,而是由前一次在同一个锁上
的自旋时间和锁的持有者状态来决定。
锁消除 :锁消除指的是 JVM 检测到一些同步的代码块,完全不存在数据竞争的场景,也就是不需要
加锁,就会进行锁消除。
ロックの粗化 : ロックの粗化とは、多くの操作が同じオブジェクトをロックすることを指し、ロックの同期範囲が操作全体に拡張されます。
順番がずれています。
Ali 内部データ バイアス ロック : スレッドがロックを取得するために同期ブロックにアクセスすると、オブジェクト ヘッダーとスタック フレームのロック レコードにバイアス ロックのスレッドID が格納されます
このスレッドが再び同期ブロックに入るとき、ロックとロック解除に CAS は必要なく、バイアスされたロックは常に最初の行にバイアスされてロックを取得します。
プロセスでは、今後他のスレッドがロックを取得していない場合、ロックを保持しているスレッドは同期する必要はありません。そうでない場合は、他のスレッドがあるときに同期します。
スレッドがバイアスされたロックをめぐって競合すると、バイアスされたロックを保持しているスレッドがバイアスされたロックを解放します。 -XX:+UseBiasedLocking 設定を使用して 開くことができます。
バイアスロックをオンにします。
軽量ロック : JVM オブジェクトのオブジェクト ヘッダーには、いくつかのロック フラグが含まれています。コードが同期ブロックに入ると、 JVM
ロックの取得を試みるCAS メソッド。更新が成功した場合、オブジェクト ヘッダーのステータス ビットは軽量ロックとしてマークされ、更新が失敗した場合、
現在のスレッドはロックを取得するためにスピンしようとします。
ロックのアップグレード プロセス全体は非常に複雑なので、無駄なリンクをいくつか削除し、アップグレード メカニズム全体を簡単に説明するよう最善を尽くします。
簡単に言うと、バイアスされたロックはオブジェクト ヘッダーのバイアスされたスレッド IDによって 比較され、 CASさえ必要ありませんが 、軽量ロックは主に
これは、オブジェクトのヘッド ロック レコードを変更し、 CASをスピンする ことで実現され 、ヘビーウェイト ロックは、ロックを所有するスレッドを除いてブロックされます。
24. プロセスとスレッドの違いについて教えてください。
1. 进程是一个 执行中的程序 ,是系统进行资源分配和调度的一个独立单位。
2. 线程是进程的一个实体,一个进程中拥有多个线程,线程之间共享地址空间和其它资源(所以
通信和同步等操作线程比进程更加容易)
3. 线程上下文的切换比进程上下文切换要快很多。
1 )进程切换时,涉及到当前进程的 CPU 环境的保存和新被调度运行进程的 CPU 环境的设置。
2 )线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。
阿里内部资料 25 ,产生死锁的四个必要条件?
1. 互斥条件:一个资源每次只能被一个线程使用
2. 请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放
3. 不剥夺条件:进程已经获得的资源,在未使用完之前,不能强行剥夺
4. 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系
26 、如何避免死锁?
指定获取锁的顺序,举例如下:
1. たとえば、スレッドは A ロックと Bロックを取得した場合に のみリソース上で動作できます。マルチスレッド条件下でデッドロックを回避するにはどうすればよいですか?
2.ロックの取得順序は一定であり、例えば、 Aロック を取得したスレッドのみが Bロックを取得できると規定されており、順番にロックを取得できます。
デッドロックを避けるために!
27. スレッド プール内のコア スレッドの数を設定するにはどうすればよいですか?
CPU 集中型と IO 集中型に分けられる
CPU
この種のタスクは主に CPU リソースを消費するため、スレッド数は CPUコア数よりも多いN ( CPU コア数) +1に設定できます。
スレッドが来るのは、スレッドが時折ページ フォールトで中断されることや、他の理由によるタスクの一時停止の影響を防ぐためです。一度
タスクが一時停止されると、 CPU は アイドル状態になり、この場合、追加のスレッドが CPU のスペースを最大限に活用できます。
自由時間。
I/O 集中型
この種のタスクが適用されると、システムはほとんどの時間をI/Oインタラクション の処理に費やし 、スレッドは I/O時間 を占有しません。
CPU 来处理,这时就可以将 CPU 交出给其它线程使用。因此在 I/O 密集型任务的应用中,我们
可以多配置一些线程,具体的计算方法是 :
核心线程数 =CPU 核心数量 *2
28 Java 线程池中队列常用类型有哪些?
ArrayBlockingQueue 是一个基于数组结构的 有界阻塞队列 ,此队列按 FIFO (先进先出)原则
对元素进行排序。
LinkedBlockingQueue 一个基于链表结构的 阻塞队列 ,此队列按 FIFO (先进先出)
排序元
素,吞吐量通常要高于 ArrayBlockingQueue
SynchronousQueue 一个不存储元素的 阻塞队列
PriorityBlockingQueue 一个具有优先级的 无限阻塞队列 PriorityBlockingQueue 也是 基于
最小二叉堆实现
DelayQueue
阿里内部资料 只有当其指定的延迟时间到了,才能够从队列中获取到该元素。
DelayQueue 是一个没有大小限制的队列,
因此往队列中插入数据的操作(生产者)永远不会被阻塞,而只有获取数据的操作(消费
者)才会被阻塞。
这里能说出前三种也就差不多了,如果能说全那是最好。
29 ,线程安全需要保证几个基本特征?
原子性 ,简单说就是相关操作不会中途被其他线程干扰,一般通过同步机制实现。
可见性 ,是一个线程修改了某个共享变量,其状态能够立即被其他线程知晓,通常被解释为将
线程本地状态反映到主内存上, volatile 就是负责保证可见性的。
有序性 ,是保证线程内串行语义,避免指令重排等。
30 ,说一下线程之间是如何通信的?
线程之间的通信有两种方式:共享内存和消息传递。
共享内存
在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写 - 读内存中的公共状态来
隐式进行通信。典型的共享内存通信方式,就是通过共享对象进行通信。
例如上图线程 A 与 线程 B 之间如果要通信的话,那么就必须经历下面两个步骤:
1. 线程 A 把本地内存 A 更新过得共享变量刷新到主内存中去。
2. 线程 B 到主内存中去读取线程 A 之前更新过的共享变量。
消息传递
在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行
通信。在 Java 中典型的消息传递方式,就是 wait() notify() ,或者 BlockingQueue
31 CAS 的原理呢?
CAS 叫做 CompareAndSwap ,比较并交换,主要是通过处理器的指令来保证操作的原子性,它包含
三个操作数:
1. 变量内存地址, V 表示
2. 旧的预期值, A 表示
3. 准备设置的新值, B 表示
当执行 CAS 指令时,只有当 V 等于 A 时,才会用 B 去更新 V 的值,否则就不会执行更新操作。
32 CAS 有什么缺点吗?
阿里内部资料 CAS 的缺点主要有 3 点:
ABA 问题 ABA 的问题指的是在 CAS 更新的过程中,当读取到的值是 A ,然后准备赋值的时候仍然是
A ,但是实际上有可能 A 的值被改成了 B ,然后又被改回了 A ,这个 CAS 更新的漏洞就叫做 ABA 。只是
ABA 的问题大部分场景下都不影响并发的最终效果。
Java 中有 AtomicStampedReference 来解决这个问题,他加入了预期标志和更新后标志两个字段,
更新时不光检查值,还要检查当前的标志是否等于预期标志,全部相等的话才会更新。
循环时间长开销大 :自旋 CAS 的方式如果长时间不成功,会给 CPU 带来很大的开销。
只能保证一个共享变量的原子操作 :只对一个共享变量操作可以保证原子性,但是多个则不行,多
个可以通过 AtomicReference 来处理或者使用锁 synchronized 实现。
33 、引用类型有哪些?有什么区别?
引用类型主要分为强软弱虚四种:
1. 强引用指的就是代码中普遍存在的赋值方式,比如 A a = new A() 这种。强引用关联的对象,永
远不会被 GC 回收。
2. 软引用可以用 SoftReference 来描述,指的是那些有用但是不是必须要的对象。系统在发生内存
溢出前会对这类引用的对象进行回收。
3. 弱引用可以用 WeakReference 来描述,他的强度比软引用更低一点,弱引用的对象下一次 GC
的时候一定会被回收,而不管内存是否足够。
4. 虚引用也被称作幻影引用,是最弱的引用关系,可以用 PhantomReference 来描述,他必须和
ReferenceQueue 一起使用,同样的当发生 GC 的时候,虚引用也会被回收。可以用虚引用来管
理堆外内存。
34 、说说 ThreadLocal 原理?
hreadLocal 可以理解为线程本地变量,他会在每个线程都创建一个副本,那么在线程之间访问内部
副本变量就行了,做到了线程之间互相隔离,相比于 synchronized 的做法是用空间来换时间。
ThreadLocal 有一个静态内部类 ThreadLocalMap ThreadLocalMap 又包含了一个 Entry 数组,
Entry 本身是一个弱引用,他的 key 是指向 ThreadLocal 的弱引用, Entry 具备了保存 key value 键值对
的能力。
弱引用的目的是为了防止内存泄露,如果是强引用那么 ThreadLocal 对象除非线程结束否则始终无
法被回收,弱引用则会在下一次 GC 的时候被回收。
但是这样还是会存在内存泄露的问题,假如 key ThreadLocal 对象被回收之后, entry 中就存在 key
これは nullです が、 値には エントリ オブジェクトがありますが、アクセスすることはできず、スレッドの実行が終了しない限り同じです。
ただし、 ThreadLocalが適切に使用されている 限り、 使用後に Removeメソッドを呼び出して Entryオブジェクト を削除しても 、実際には問題は発生しません。
さてこの問題。
内部情報もアリ 35. スレッドプールの原理をご存知ですか?およびコアパラメータ
まず、スレッド プールにはいくつかの主要なパラメーターの概念があります。
1. 最大スレッド数 maximumPoolSize
2. コアスレッド数 corePoolSize
3. アクティブ時間 keepAliveTime
4. ブロッキングキュー workQueue
5. 拒否戦略 RejectedExecutionHandler
新しいタスクをスレッド プールに送信するときの具体的な実行プロセスは次のとおりです。
1. タスクを送信すると、スレッド プールは corePoolSizeサイズに従って タスクを実行するための多数のスレッドを作成します。
2. タスクの数が corePoolSizeの数を超えると 、後続のタスクはブロッキング キューに入り、キューをブロックします。
3. 当阻塞队列也满了之后,那么将会继续创建 (maximumPoolSize-corePoolSize) 个数量的线程来
执行任务,如果任务处理完成, maximumPoolSize-corePoolSize 额外创建的线程等待
keepAliveTime 之后被自动销毁
4. 如果达到 maximumPoolSize ,阻塞队列还是满的状态,那么将根据不同的拒绝策略对应处理
阿里内部资料 36 、 线程池的拒绝策略有哪些?
主要有 4 种拒绝策略:
1. AbortPolicy :直接丢弃任务,抛出异常,这是默认策略
2. CallerRunsPolicy :只用调用者所在的线程来处理任务
3. DiscardOldestPolicy :丢弃等待队列中最旧的任务,并执行当前任务
4. DiscardPolicy :直接丢弃任务,也不抛出异常
37 、说说你对 JMM 内存模型的理解?为什么需要 JMM
CPUとメモリ の開発速度の違いの問題 では、 CPUの速度が メモリの速度よりもはるかに速いため、現在の CPUは 高速性を追加しています。
キャッシュは一般に、 L1 L2 L3 の 3 レベル キャッシュに分けることができます。上記の例に基づいて、これがキャッシュの一貫性につながることがわかります。
したがって、キャッシュ コヒーレンス プロトコルが追加され、メモリの可視性の問題、およびコンパイラと CPU の並べ替えが発生します。
これは原子性と順序の問題につながります。JMMメモリ モデルはマルチスレッド操作のため 一連の仕様制約です。
従業員 Chen のコードをすべてのCPU と 互換性のあるものにしましょう。JMMを通じて のみ、 さまざまなハードウェアとオペレーティング システムのメモリのアクセスの違いをシールドできます。
これにより、 Java プログラムがさまざまなプラットフォーム上で一貫したメモリ アクセス効果を達成できるようになり、プログラムの効率性と同時実行性も確保されます。
シーケンスを正しく実行できます。
アトミック性 : Java メモリ モデルは、 read load assign use store writeによる アトミック操作を保証します。
lock および lock は、 synchronizedキーワードのmonitorenterおよびmonitorexitバイトコード命令 に直接対応します。
Ali の内部データ の可視性 : 可視性の問題は上記の回答で述べられていますが、 Java では 可視 性を保証しています
同期され 最終的 に達成されます。
順序性 : プロセッサとコンパイラの順序変更によって生じる順序性の問題のため、 Java は volatilesynchronized 使用して、
証明書。
前発生 ルール
命令の再配置により並行性のパフォーマンスが向上しますが、 Java 仮想マシンでは命令の再配置にいくつかのルールが課されており、すべての命令が許可されるわけではありません。
命令の実行位置はランダムに変更されます。主なポイントは次のとおりです。
1. 単一スレッド内の各操作について、 スレッド内の後続の操作 の前に発生します。
2. 揮発性 書き込みは 、この変数の読み取りの 前とその後の読み取りで発生します。
3. 同期 ロック解除は 、このロックの後続のロック の前に行われます。
4. fifinal変数 の書き込みは、fifinalドメイン オブジェクトの読み取りの 前に発生し 、その後のfifinal変数の読み取りの前に発生します。
5. 推移的なルール、 A は B に先行し B はCに先行しA はCより前に出現する必要があります。
長く話していると、ワーキングメモリとメインメモリとは何ですか?
メイン メモリは物理メモリと考えることができ、実際には Java メモリ モデルでは仮想マシン メモリの一部です。そしてワーキングメモリは
CPU キャッシュ、レジスタ、または L1/L2/L3 キャッシュのいずれかが可能です。
38. マルチスレッドの用途は何ですか?
多くの人にとってはナンセンスに思えるかもしれない質問です。マルチスレッドを使用できますが、それは何に役立ちますか? 私の意見では、これは
この答えはさらにナンセンスです。いわゆる それが何であるかを知っており 、それがなぜであるかを知っている」、「それの使用方法を知っている」は単に「それが何であるかを知っている だけありなぜそれ使用するか」それがなぜであるかを知っている」だけです
知識ポイントは、 「 それが何であるかを知り、なぜそうなるのかを知る というレベルに達して初めて自由に使用できると言えます OK 、私の問題について話しましょう
の意見:
( 1 )マルチコア CPU を活用する
業界の進歩に伴い、現在のノートブック、デスクトップ、さらには商用アプリケーション サーバーは少なくともデュアルコア、 4 コア、 8 コア、あるいはさらにはコアになっています。
16 コアは珍しいことではなく、シングル スレッド プログラムの場合、デュアル コア CPUでは 50% が無駄になり 4コアCPUでは 50% が無駄になります。
最大 75% シングルコア CPUの いわゆる マルチスレッド は偽のマルチスレッドです。プロセッサは同時にロジックの一部を処理するだけですが、
スレッド間の切り替えは比較的高速で、複数のスレッドが 同時に 実行されている ように見えます。マルチコア CPU上のマルチスレッド が本当のマルチスレッドです
プログラムでは、複数のロジックを同時に動作させることができ、マルチスレッド化により、マルチコア CPU を最大限に活用し て最大限の利用率を達成できます。
CPUの目的
( 2 ) ブロッキングを防ぐ
プログラムの実行効率の観点から、シングルコア CPU は マルチスレッドを利用できないだけでなく、シングルコア CPU上でも 実行されます。
マルチスレッドではスレッド コンテキストの切り替えが発生し、プログラム全体の効率が低下します。ただし、シングルコア CPU にはマルチスレッドを適用する必要があります。
あくまでブロッキングを防ぐためです。シングルコア CPU が 単一のスレッドを使用する場合、このスレッドがブロックされている限り (リモート読み取りなど) を想像してください。
一部のデータについては、ピアが長期間返されず、タイムアウト期間が設定されていない場合、データが返される前にプログラム全体が停止します。
アリの内部データ は実行されています。マルチスレッドを使用すると、この問題を防ぐことができます。1 つのスレッドのコード実行がデータの読み取りのためにブロックされている場合でも、複数のスレッドが同時に実行されます。
他のタスクの実行には影響しません。
3 )便于建模
这是另外一个没有这么明显的优点了。假设有一个大的任务 A ,单线程编程,那么就要考虑很多,
建立整个程序模型比较麻烦。但是如果把这个大的任务 A 分解成几个小任务,任务 B 、任务 C 、任务
D ,分别建立程序模型,并通过多线程分别运行这几个任务,那就简单很多了。
39 、说说 CyclicBarrier CountDownLatch 的区别?
两个看上去有点像的类,都在 java.util.concurrent 下,都可以用来表示代码运行到某个点上,二者
的区别在于:
1 CyclicBarrier 的某个线程运行到某个点上之后,该线程即停止运行,直到所有的线程都到达了
这个点,所有线程才重新运行; CountDownLatch 则不是,某线程运行到某个点上之后,只是给某
个数值 -1 而已,该线程继续运行
( 2 ) CyclicBarrier は 1 つのタスクのみを呼び出すことができ、 CountDownLatch は 複数のタスクを呼び出すことができます
( 3 ) CyclicBarrier は 再利用できますが、 CountDownLatch は 再利用できません。カウント値が 0の場合、 CountDownLatch 使用できなくなります。
使用済み
40. AQS とは何ですか
AQS について簡単に説明します 。AQS の正式名はAbstractQueuedSychronizerで、抽象キュー シンクロナイザーと 翻訳 する必要があります。
java.util.concurrentの基礎が CAS である 場合AQS はJava並行パッケージ全体の中核となります
ReentrantLock CountDownLatch Semaphoreなど で使用されます。 AQS は 実際には双方向キューの形式です
ReentrantLockなどのすべての Entryを接続します 。すべての待機スレッドはEntryに配置され、双方向キューに接続されます。
前のスレッドが ReentrantLockを使用する と、双方向キューの実際の最初の エントリ が実行を開始します。
AQS は 双方向キュー上のすべての操作を定義し、 開発者が使用できる tryLockメソッド tryReleaseメソッドのみを開きます。
独自の実装に従って tryLockメソッド tryReleaseメソッドを書き換えて 、独自の同時関数を実現できます。
41. セマフォを 理解していますか ?
Emaphore はセマフォであり、その機能は 特定のコード ブロックの同時実行数を制限すること です。 セマフォに はコンストラクターがあり、
int 整数nを に渡すことができ、特定のコード 最大n個のスレッドによってのみアクセスできることを示します。 nを超える場合はお待ちください。
スレッドがこのコード ブロックの実行を終了するまで待ってから、次のスレッドに進みます。このことから、 セマフォ コンストラクターが
受信する int 整数 n=1は、 synchronized になるのと同じです
42. CallableとFutureと は何ですか ?
Ali 内部データ Callableインターフェイスは 、名前からわかるようにRunnable に似ていますが、 Runnable は結果を返さず、スローすることはできません
結果を返す例外であり、 Callable 関数がより強力です。スレッドによって実行された後、値を返すことができ、この戻り値を使用できます。
Future は それを取得します。つまり、 Future は 非同期実行タスクの戻り値を取得できます。コールバックとして考えることができます
実行可能
Future インターフェイスは、まだ完了していないタスクによって与えられる将来の結果である非同期タスクを表します。したがって、結果を生成するために Callable が使用されます。
Future は 結果を取得するために使用されます。
43. ブロッキングキューとは何ですか? ブロッキングキューの実装原理は何ですか? ブロッキングの使い方
キューをプラグインしてプロデューサー - コンシューマー モデルを実装しますか?
ブロッキング キュー ( BlockingQueue ) は、2 つの追加操作をサポートするキューです。
这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元
素的线程会等待队列可用。
阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿
元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。
JDK7 提供了 7 个阻塞队列。分别是:
ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
DelayQueue :一个使用优先级队列实现的无界阻塞队列。
SynchronousQueue :一个不存储元素的阻塞队列。
LinkedTransferQueue :一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque :一个由链表结构组成的双向阻塞队列。
Java 5 之前实现同步存取时,可以使用普通的一个集合,然后在使用线程的协作和线程同步可以实
现生产者,消费者模式,主要的技术就是用好, wait ,notify,notifyAll,sychronized 这些关键字。而
java 5 之后,可以使用阻塞队列来实现,此方式大大简少了代码量,使得多线程编程更加容易,
安全方面也有保障。
BlockingQueue 接口是 Queue 的子接口,它的主要用途并不是作为容器,而是作为线程同步的的工
具,因此他具有一个很明显的特性,当生产者线程试图向 BlockingQueue 放入元素时,如果队列已
满,则线程被阻塞,当消费者线程试图从中取出一个元素时,如果队列为空,则该线程会被阻塞,
正是因为它所具有这个特性,所以在程序中多个线程交替向 BlockingQueue 中放入元素,取出元
素,它可以很好的控制线程之间的通信。
阻塞队列使用最经典的场景就是 socket 客户端数据的读取和解析,读取数据的线程不断将数据放入
队列,然后解析线程不断从队列取数据解析。
44 、什么是多线程中的上下文切换?
阿里内部资料 在上下文切换过程中, CPU 会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后
继续运行。从这个角度来看,上下文切换有点像我们同时阅读几本书,在来回切换书本的同时我们
需要记住每本书当前读到的页码。
在程序中,上下文切换过程中的 页码 信息是保存在进程控制块( PCB )中的。 PCB 还经常被称
スイッチフレーム switchframe ) の場合 ページ番号 」情報は、再度使用されるまで常に CPUのメモリ に保存されます。
コンテキストの切り替えは、 CPU の状態 を保存および復元するプロセスであり 、これにより、スレッドの実行が中断された時点から実行を再開できるようになります。コンテキストスイッチは
マルチタスク オペレーティング システムとマルチスレッド環境の基本特性。
45. デーモンスレッド とは何ですか ? それはどういう意味ですか?
いわゆるバックグラウンド (デーモン) スレッドは、デーモン スレッドとも呼ばれ、プログラムの実行中にバックグラウンドで一般的なサービスを提供するスレッドを指します。
そして、このスレッドはプログラムに不可欠な部分ではありません。
したがって、バックグラウンド以外のスレッドがすべて終了すると、プログラムは終了し、プロセス内のすべてのバックグラウンド スレッドが強制終了されます。順番に
説明、
バックグラウンド以外のスレッドが実行されている限り、プログラムは終了しません。
setDaemon()メソッドは 、スレッドが バックグラウンド スレッドとして設定を開始する前に呼び出す必要があります。注: バックグラウンドプロセスは実行されていません
fifinally 節は run() メソッドを終了します。
例: JVMのガベージ コレクション スレッドは デーモンスレッド であり ファイナライザーもデーモン スレッドです。
46. 楽観的ロックと悲観的ロックについてどのように理解していますか?また、それらを実装する方法は何ですか?
悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候
都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。
传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做
操作之前先上锁。再比如 Java 里面的同步原语 synchronized 关键字的实现也是悲观锁。
乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是
在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。
乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于 write_condition
制,其实都是提供的乐观锁。
Java java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS
现的。
乐观锁的实现方式:
1 、使用版本标识来确定读到的数据与提交时的数据是否一致。提交后修改版本标识,不一致时可
以采取丢弃和再次尝试的策略。
阿里内部资料 2 java 中的 Compare and Swap CAS ,当多个线程尝试使用 CAS 同时更新同一个变量时,只有其
スレッドの 1 つが変数の値を更新できる一方で、他のスレッドが失敗すると、失敗したスレッドは一時停止されませんが、競合が通知されます。
失敗しましたが、再試行できます。 CAS演算には、 読み書きされるメモリ位置 ( V )、比較という 3 つのオペランドが含まれます
期待される元の値 ( A ) と書き込まれる新しい値 (B)を比較します メモリ位置V の値が 予想される元の値 Aと一致する場合 、プロセッサは自動的に
位置の値を新しい Bに自動的に更新します。 それ以外の場合、プロセッサは何も行いません。
CASの欠点 :
1. ABA 問題: たとえば、スレッド 1 が メモリ位置 Vから A を取り出し 、この時点で別のスレッド2もメモリから A を取り出します。
A 、および 2 つが B になるためにいくつかの操作を実行し 、次に2 つがV位置のデータをA変更しました。このとき、スレッド1 が実行しました
CAS操作では、メモリに A が まだ存在することがわかり 1 つの操作は成功します。スレッド1CAS操作は成功しましたが、問題が発生する可能性があります。
隠れた問題。 Java1.5 以降、 JDKアトミックパッケージ には、 解決するためのクラスAtomicStampedReferenceが提供されています。
ABA の問題。
2. 長いサイクル時間と高コスト: 激しいリソース競合 (深刻なスレッド競合) では、 CAS スピンの確率が比較的高くなります。
したがって、より多くの CPU リソースが浪費されるため、効率は synchronizedよりも低くなります
3. 保証できるのは 1 つの共有変数のアトミック操作のみです。 共有変数に対して操作を実行する場合、 ループ CASを使用できます。
アトミック操作を保証する方法ですが、複数の共有変数を操作する場合、循環 CAS は 操作のアトミック性を保証できません。
ロックが使えるとき。
WeChat パブリック アカウントにご注目ください: Java バックエンド テクノロジのフルスタック
_
1.春と は何ですか ?
Spring 是个 java 企业级应用的开源开发框架。 Spring 主要用来开发 Java 应用,但是有些扩展是针对
构建 J2EE 平台的 web 应用。 Spring 框架目标是简化 Java 企业级应用开发,并通过 POJO 为基础的编程
模型促进良好的编程习惯。
2 、你们项目中为什么使用 Spring 框架?
这么问的话,就直接说 Spring 框架的好处就可以了。比如说 Spring 有以下特点:
轻量: Spring 是轻量的,基本的版本大约 2MB
控制反转: Spring 通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找
依赖的对象们。
面向切面的编程 (AOP) Spring 支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
容器: Spring 包含并管理应用中对象的生命周期和配置。
MVC 框架 Spring WEB 框架是个精心设计的框架,是 Web 框架的一个很好的替代品。
事务管理: Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务
JTA )。
阿里内部资料 异常处理: Spring 提供方便的 API 把具体技术相关的异常(比如由 JDBC Hibernate or JDO
出的)转化为一致的 unchecked 异常。
3 Autowired Resource 关键字的区别?
@Resource @Autowired 都是做 bean 的注入时使用,其实 @Resource 并不是 Spring 的注解,它的
パッケージは javax.annotation.Resourceであり 、インポートする必要がありますが、 Spring は このアノテーションの注入をサポートしています。
1. 共通点
どちらもフィールドとセッターメソッド に記述できます 両方がフィールドに記述されている場合は、 setter メソッドを記述する必要はありません。
2. 相違点
1 @Autowired
@Autowiredによって Spring 提供されるアノテーションは、パッケージをインポートする必要があります
org.springframework.beans.factory.annotation.Autowired; byTypeに従って のみ 挿入されます。
@Autowiredアノテーションは、タイプ ( byType ) に従って依存オブジェクトをアセンブルします 。デフォルトでは、依存オブジェクトが存在する必要があります。
null値 を許可する場合は、そのrequired属性をfalseに 設定できます 名前によるインストール ( byName ) を使用する場合
@Qualifierアノテーション と組み合わせて使用​​できます 次のように:
2 @リソース
パブリック クラス TestServiceImpl {
// 次の 2 つの @Autowired のうち 1 つだけを使用する必要があります。
@Autowired
private UserDao userDao ; // フィールドで使用されます
@Autowired
public void setUserDao ( UserDao userDao ) { // プロパティメソッドで使用されます
これ ユーザーダオ = ユーザーダオ ;
}
}
パブリック クラス TestServiceImpl {
@Autowired
@Qualifier ( "userDao" )
プライベート UserDao userDao ;
}
Ali の内部データ @Resource は、 デフォルトで J2EEによって提供される ByNameによって 自動的に挿入され 、パッケージjavax.annotation.Resourceをインポートする必要があります
@Resource 有两个重要的属性: name type ,而 Spring @Resource 注解的 name 属性解析为
bean 的名字,而 type 属性则解析为 bean 的类型。所以,如果使用 name 属性,则使用 byName 的自
动注入策略,而使用 type 属性时则使用 byType 自动注入策略。如果既不制定 name 也不制定 type
性,这时将通过反射机制使用 byName 自动注入策略。
注:最好是将 @Resource 放在 setter 方法上,因为这样更符合面向对象的思想,通过 set get 去操
作属性,而不是直接去操作属性。
@Resource 装配顺序:
①名前 を同時に指定した場合 アセンブリ用の Springコンテキストから 唯一一致する Beanを検索し、見つからない場合はスローする
例外。
②name を指定した場合、コンテキストから名前( id )が一致するBean を探して アセンブルします。見つからない場合は例外がスローされます。
③ type が指定されている場合 、アセンブリのコンテキストから一致に類似した一意の Beanを検索します 。見つからない場合、または複数の Bean が見つからない場合は、
例外をスローします。
名前 型も指定しない場合は byNameメソッド に従って自動的に アセンブルされ、一致するものがない場合は、
プリミティブ型の一致にフォールバックし、一致する場合は自動配線します。
@Resource の役割は、 @Autowired がbyTypeに従って自動的に挿入されることを除いて、 @Autowiredと同等です
4. 依存性注入にはいくつかの方法がありますが、それは何ですか ?
1. コンストラクター の注入のパラメーターを通じて依存オブジェクトを依存オブジェクトに注入します。オブジェクトの初期化時の注意事項
入力。
アドバンテージ:
オブジェクトの初期化が完了すると、使用可能なオブジェクトを取得できます。
欠点:
注入されるオブジェクトが多数ある場合、コンストラクターのパラメーターのリストは非常に長くなります。
十分な柔軟性がありません。複数の注入方法がある場合、それぞれ
このメソッドでは、いくつかの依存関係を挿入して指定するだけで済みます。その後、複数のオーバーロードされたコンストラクターを提供する必要がありますが、これは面倒です。
パブリック クラス TestServiceImpl {
// 次の 2 つの @Resource の うち 1 つだけを使用する必要があります
@Resource ( name = "userDao" )
private UserDao userDao ; // フィールドで使用されます
@Resource ( name = "userDao" )
public void setUserDao ( UserDao userDao ) { //プロパティの セッターメソッドで 使用されます
これ ユーザーダオ = ユーザーダオ ;
}
}
Ali 内部情報 2. Setter メソッドのインジェクション IoC Service Provider は、 メンバ変数が提供する setter関数を呼び出すことで、 依存オブジェクトにインジェクションされます。
依存クラス。
アドバンテージ:
フレキシブル。必要なオブジェクトを選択して注入できます。
欠点:
依存オブジェクトが初期化された後は、依存オブジェクトが挿入されていないため、まだ使用できません。
3. インターフェイスの挿入 依存クラスは、指定されたインターフェイスを実装し、依存関係に使用されるインターフェイスに関数を実装する必要があります。
注入。この関数のパラメータは、注入されるオブジェクトです。
利点 インターフェイスの注入では、関数のパラメーターが注入されるオブジェクトの型である限り、インターフェイスの名前と関数の名前は重要ではありません。
できる。
欠点:
侵入的なラインは強すぎるため、お勧めできません。
PS : 侵入行とは何ですか?
クラスA が他の人が提供する関数を使用したい場合、その関数を使用するには、クラス A が独自のクラスに存在する必要があります。
余分なコードを追加することは侵襲的です。
5. とは何か教えてください
Spring は 、軽量の IoC および AOP コンテナー フレームワークです。これは、 Javaアプリケーションに 基本的なサービスを提供するフレームワークのセットです。
エンタープライズ アプリケーションの開発を簡素化するために使用されるため、開発者はビジネス ニーズのみに気を配ることができます。一般的な構成方法は 3 つあります。
XML 構成、アノテーションベースの構成、および Java ベースの構成。
主に次のモジュールで構成されます。
Spring Core : IOC サービスを提供するコア クラス ライブラリ。
Spring Context : フレームワーク スタイルの Bean アクセス メソッドとエンタープライズ レベルの機能 ( JNDI 、スケジュールされたタスクなど) を提供します。
Spring AOP : AOP サービス。
Spring DAO : JDBCの抽象化により 、データ アクセス例外の処理が簡素化されます。
Spring ORM : 既存の ORMフレームワーク のサポート
Spring Web : マルチパーティ ファイルのアップロードなど、基本的な Web指向の包括的な機能を提供します。
Spring MVC : Web アプリケーションの Model-View-Controller実装を提供します
6. Spring MVCについての理解 について話す
MVC パターンとは何ですか
MVC : MVC は デザインパターンです
MVC の概略図:
アリの内部データ 分析:
M-Model モデル (完全なビジネス ロジック: javaBean service+dao+entityで構成される )
V-View ビュー (インターフェース表示 jsp html...を実行します )
C-Controller コントローラ (リクエストを受信 —> モデルを呼び出し —> 結果に応じてページをディスパッチ)
springMVCは MVCのオープンソース フレームワーク です springMVC=struts2+spring springMVCはStruts2と同等です。
sringの統合 です が、ここで疑問があります。 springMVC spring の関係は何ですか? これは百度にあります
百科事典には詳しい説明があります。これは、 springMVC が spring のフォローアップ製品で あることを意味します。実際、 オリジナルではspringです。
これに基づいて、 Web アプリケーション用の MVCモジュールも提供されており springMVC を Springのモジュール として簡単に理解できます。
( AOP IOCなどのモジュール)、 springMVCspring はシームレスに統合されている とインターネットでよく言われ ます
これは spring のサブモジュールであるため、 springと 統合する必要はまったくありません。
動作原理:
Ali 内部情報 1.ユーザーはフロント コントローラー DispatcherServlet にリクエストを送信します
2. DispatcherServlet は、リクエストを受信する と、 HandlerMappingプロセッサ マッパー を呼び出します。
3. プロセッサ マッパーは特定のプロセッサを検索し ( XML設定とアノテーションに従って検索 できます ) 、プロセッサ オブジェクトとプロセッサを生成します。
インターセプタ ( 存在する場合は生成される )も DispatcherServlet に返されます
4. DispatcherServlet は HandlerAdapter プロセッサ アダプタ を呼び出します
5. HandlerAdapter は、適応後に特定のプロセッサ(Controller バックエンド コントローラとも呼ばれる)を呼び出します
6 Controller 执行完成返回 ModelAndView
7 HandlerAdapter controller 执行结果 ModelAndView 返回给 DispatcherServlet
8 DispatcherServlet ModelAndView 传给 ViewReslover 视图解析器。
9 ViewReslover 解析后返回具体 View
10 DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
11 DispatcherServlet 响应用户。
组件说明:
以下组件通常使用框架提供实现:
DispatcherServlet :作为前端控制器,整个流程控制的中心,控制其它组件执行,统一调度,降低
组件之间的耦合性,提高每个组件的扩展性。
Ali 内部データ HandlerMapping : プロセッサ マッパーを拡張することで、さまざまなマッピング メソッドを実装します。例: 構成ファイル メソッド、インターフェイス実装
メソッド、アノテーションメソッドなど。
HandleAdapter : プロセッサ アダプタを拡張することで、より多くの種類のプロセッサをサポートします。
ViewResolver : ビュー リゾルバーを拡張することで、より多くの種類のビュー解像度 ( jsp freemarker pdfなど) がサポートされます
エクセル など
コンポーネント:
1. フロントエンドコントローラー DispatcherServlet (エンジニアの育成不要)
フレームワークによって提供されます。 機能: リクエストの受信、応答
結果は、中継器、中央処理装置に相当するはずです。 dispatcherServlet を使用すると 、他のコンポーネント間の結合が軽減されます。ユーザー
リクエストがフロントコントローラーに到着すると、それは mvcモード cに相当し dispatcherServlet が プロセス制御全体の中心となり、それによって制御されます。
他のコンポーネントを呼び出してユーザー要求を処理し、 dispatcherServletの存在により コンポーネント間の結合が軽減されます。
2 、处理器映射器 HandlerMapping( 不需要工程师开发 ), 由框架提供 作用:根据请求的 url 查找
Handler HandlerMapping 负责根据用户请求找到 Handler 即处理器, springmvc 提供了不同的映射
器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3 、处理器适配器 HandlerAdapter 作用:按照特定规则( HandlerAdapter 要求的规则)去执行
Handler 通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对
更多类型的处理器进行执行。
4 、处理器 Handler( 需要工程师开发 ) 注意:编写 Handler 时按照 HandlerAdapter 的要求去做,
这样适配器才可以去正确执行 Handler Handler 是继 DispatcherServlet 前端控制器的后端控制器,
DispatcherServlet 的控制下 Handler 对具体的用户请求进行处理。 由于 Handler 涉及到具体的用
户业务请求,所以一般情况需要工程师根据业务需求开发 Handler
5 、视图解析器 View resolver( 不需要工程师开发 ), 由框架提供 作用:进行视图解析,根据逻辑视图
名解析成真正的视图( view View Resolver 负责将处理结果生成 View 视图, View Resolver 首先根
据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将
处理结果通过页面展示给用户。 springmvc 框架提供了很多的 View 视图类型,包括: jstlView
freemarkerView pdfView 等。 一般情况下需要通过页面标签或页面模版技术将模型数据通过页面
展示给用户,需要由工程师根据业务需求开发具体的页面。
6 、视图 View( 需要工程师开发 jsp...) View 是一个接口,实现类支持不同的 View 类型( jsp
freemarker pdf...
核心架构的具体流程步骤如下: 1 、首先用户发送请求 ——>DispatcherServlet ,前端控制器收到
请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控
制; 2 DispatcherServlet——>HandlerMapping HandlerMapping 将会把请求映射为
HandlerExecutionChain 对象(包含一个 Handler 处理器(页面控制器)对象、多个
HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略; 3
DispatcherServlet——>HandlerAdapter HandlerAdapter 将会把处理器包装为适配器,从而支
複数の種類のプロセッサをサポートする、つまりアダプタ設計パターンの適用により、多くの種類のプロセッサをサポートすることが容易になり ます
HandlerAdapter --> プロセッサ関数の呼び出し処理メソッド 。HandlerAdapter は 適応結果に従って true を呼び出します。
アリババの内部データのプロセッサの関数処理メソッドは 、関数処理を完了し、 ModelAndView オブジェクト (モデル データ、ロジックを含む)を返します。
edit view name); 5. ModelAndView --> ViewResolverの論理ビュー名 ViewResolver は論理ビューを変換します
名前は特定の Viewに解決されます 。この戦略モードを通じて、他のビュー テクノロジを簡単に置き換えることができます。6 . ビュー - >レンダリング、ビュー
受信したModelモデル データ に従ってレンダリングされます。 ここでの Model は実際には Mapデータ構造 ので、サポートが簡単です
他のビュー テクノロジをサポートします。 7.制御を DispatcherServlet に戻す と、DispatcherServlet はユーザーに応答を返します。
このプロセスは終了します。
これらの手順を見ると、誰もが非常に面倒に感じると思いますが、これは正常なことですが、ここでは主に springMVC を理解してもらうことを目的としています。
以下のいくつかのコンポーネント:
フロントエンド コントローラー ( DispatcherServlet ): リクエストを受信し、結果に応答します。コンピューターの CPU に相当します
プロセッサ マッパー ( HandlerMapping ): URLに従って プロセッサを検索します。
プロセッサ ( ハンドラー ): プログラマは、ロジックを処理するコードを記述する必要があります。
プロセッサ アダプタ ( HandlerAdapter ): 複数のタイプの処理をサポートできるように、プロセッサはアダプタにパッケージ化されます。
このアダプターは、ノートブックのアダプター (アダプター モードのアプリケーション) に似ています。
View Resovler ( ViewResovler ): ビュー解決を実行し、返された文字列を処理し、対応するページに解析します。
麺。
7. SpringMVCの一般的なアノテーションは 何ですか?
@RequestMapping : リクエスト URLマッピング を処理するためのアノテーション 。クラスまたはメソッドで使用できます。クラスで使用される場合、そのクラス内で
リクエストに応答するすべてのメソッドは、このアドレスを親パスとして使用します。
@RequestBody : アノテーションは、 http リクエストの jsonデータを受信し その json を Javaオブジェクト に変換することを実現します
@ResponseBody : アノテーション実装は、 conreollerメソッドによって返されたオブジェクトを jsonオブジェクト に変換して 、クライアントに応答します。
8. SpringAOPについての理解 について話す
AOP ( アスペクト指向プログラミング 、アスペクト指向プログラミング) は、ビジネスとは関係のないものを統合できますが、
一般的に呼び出されるロジックや責任 (トランザクション処理、ログ管理、アクセス制御など) は、システムの重複を減らすためにカプセル化されます。
コードを統合し、モジュール間の結合を減らし、将来の拡張性と保守性を促進します。
Spring AOP は動的プロキシに基づいており、プロキシされるオブジェクトがインターフェイスを実装している場合、 Spring AOPは JDK を使用します。
プロキシ オブジェクトを作成するための動的プロキシ。インターフェイスを実装していないオブジェクトの場合、 JDK 動的プロキシは 使用できず、代わりに CGlibが使用されます。
動的プロキシは、プロキシされたオブジェクトのサブクラスをプロキシとして生成します。
Ali の内部情報の注記: 図の 実装 拡張 つまり、1 つはインターフェイスで、もう 1 つは実装クラスです。
もちろん、 AspectJ も使用できますが AspectJ は Spring AOP に統合されており AspectJ はJavaエコシステムと見なす必要があります
最も完全な AOP フレームワーク。 AOP を使用すると 、いくつかの一般的な関数を抽象化し、必要な場所で直接使用できるようになります。
これを使用するだけで、コードの量を大幅に簡素化できます。新しい機能を便利に追加し、システムの拡張性を向上させる必要があります。ログ機能
AOP は、 パフォーマンス、トランザクション管理、権限管理などのシナリオで使用されます
ここでAspectJ について 言及している限り 、面接官はおそらく次のことを質問し続けるでしょう。
9. Spring AOPAspectJ AOPの違いは 何ですか ?
Spring AOP は実行時の拡張機能ですが、 AspectJ はコンパイル時の拡張機能です。 Spring AOP はプロキシ ( Proxying ) に基づいており、
AspectJ はバイトコード操作 ( Bytecode Manipulation ) に基づいています。
Spring AOPには AspectJ が統合されており AspectJ はJavaエコシステムで最も完全なAOPフレームワークと見なされるべきです
AspectJは Spring AOP よりも 強力ですが、 Spring AOPは比較的単純です。
アスペクトの数が少ない場合、2 つの間のパフォーマンスの差は大きくありません。ただし、アスペクトが多すぎる場合は、 AspectJ を選択するの が最善です。
Spring AOP は はるかに高速です。
続けて次のように質問する場合があります。
Spring AOP では 、懸念事項と横断的懸念事項の違いは何ですか?
懸念事項はアプリケーション内のモジュールの動作であり、懸念事項は達成したい機能として定義される場合があります。切り取られたクロス
アノテーションはアプリケーション全体で使用され、ロギング、セキュリティ、データなどのアプリケーション全体に影響を与える機能です。
送信によると、アプリケーションのほぼすべてのモジュールがその機能を必要とします。したがって、これらは横断的な懸念事項です。
では、結合ポイントとは何でしょうか? 結合ポイントは、 AOP カットを挿入できるアプリケーション内の場所を表します。
表面的には、実際にはアプリケーションが Spring AOPを実行する場所です
アリの内部情報 の入り口は何ですか?ポイントカットは、アドバイスが実行される結合ポイントまたは結合ポイントのセットです。表現または一致させることができる
式はエントリーポイントを示します。
通知とは何ですか? どのような種類がありますか?
通知はメソッドの実行前または後に実行されるアクションであり、実際には、プログラムの実行時に Spring AOPフレームワークによって トリガーされるプロキシです。
コードセグメント。
Spring アスペクトでは、次の 5 種類のアドバイスを適用できます。
before : 事前アドバイス。メソッドが実行される前に呼び出されます。
after: メソッドの実行が成功したかどうかに関係なく、メソッドの実行後に呼び出される通知。
after-returning: メソッドが正常に完了した後にのみ実行される通知。
after-throwing: 例外がスローされてメソッドが終了したときに実行される通知。
around: メソッドの実行前後に呼び出されるアドバイス。
10. SpringIOCについてのあなたの理解 を教えてください。
( 1 ) IOC は制御の反転であり、オブジェクトを作成するための制御権の譲渡を指します。かつては、ものづくりの主導権やタイミングは自分たちで決められていました。
制御され、この権限が Spring コンテナーに転送され、コンテナーがインスタンスを作成し、構成ファイルに従って各インスタンスを管理します。
間の依存関係。オブジェクト間の疎結合は、関数の再利用にも役立ちます。 DI 依存関係の注入 (制御の反転と同じ)
概念的不同角度的描述,即 应用程序在运行时依赖 IoC 容器来动态注入对象需要的外部资源。
2 )最直观的表达就是, IOC 让对象的创建不用去 new 了,可以由 spring 自动生产,使用 java 的反
射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的。
3 Spring IOC 有三种注入方式 :构造器注入、 setter 方法注入、根据注解注入。
IoC 让相互协作的组件保持松散的耦合,而 AOP 编程允许你把遍布于应用各层的功能分离出来
形成可重用的功能组件。
11 、解释一下 spring bean 的生命周期
首先说一下 Servlet 的生命周期:实例化,初始 init ,接收请求 service ,销毁 destroy
Spring 上下文中的 Bean 生命周期也类似,如下:
( 1 ) Beanをインスタンス化します
BeanFactoryコンテナ の場合、クライアントが コンテナから初期化されていない Beanを要求した場合 、または Beanが初期化された 場合、注意が必要です。
初期化されていない別の依存関係をインポートする場合、コンテナーは createBean を呼び出してインスタンス化します。 ApplicationContext コンテンツの場合
コンテナが起動すると、 BeanDefinitionオブジェクト内の情報を取得して すべての Bean がインスタンス化されます
Ali 内部データ ( 2 ) セット オブジェクト プロパティ (依存性注入):
インスタンス化されたオブジェクトは BeanWrapper オブジェクトにカプセル化され、 Spring は BeanDefinition内の情報を 使用して
そして、 BeanWrapper が提供するプロパティを設定するためのインターフェースを介して依存関係の注入を完了します。
( 3 ) Aware インターフェイスを処理します。
次に、 Spring は オブジェクトが xxxAware インターフェースを実装しているかどうかを検出し、関連する xxxAware インスタンスを Beanに注入します
①Bean BeanNameAwareインターフェース を実装している場合 setBeanName(String
beanId)メソッドでは、 Spring構成ファイル内のBeanID値 がここに渡されます
②Bean BeanFactoryAwareインタフェース を実装している場合、 実装しているsetBeanFactory()メソッドを呼び出し、
納品されるのは スプリング 工場そのものです。
③Beanが ApplicationContextAwareインターフェースを実装している場合、 Bean
setApplicationContext(ApplicationContext) メソッド 。Spring コンテキストに渡します。
4 BeanPostProcessor
如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,那将会
调用 postProcessBeforeInitialization(Object obj, String s) 方法。
5 InitializingBean init-method
如果 Bean Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
6 )如果这个 Bean 实现了 BeanPostProcessor 接口,将会调用
postProcessAfterInitialization(Object obj, String s) 方法;由于这个方法是在 Bean 初始化结束时调
用的,所以可以被应用于内存或缓存技术;
以上几个步骤完成后, Bean 就已经被正确创建了,之后就可以使用这个 Bean 了。
7 DisposableBean
Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用其实现
destroy() 方法;
8 destroy-method
最后,如果这个 Bean Spring 配置中配置了 destroy-method 属性,会自动调用其配置的销毁方
法。
阿里内部资料 12 、解释 Spring 支持的几种 bean 的作用域?
Spring 容器中的 bean 可以分为 5 个范围:
( 1 ) singleton : デフォルトでは、各コンテナーには Beanインスタンス が 1 つだけあり 、シングルトン モードはBeanFactory自体によって維持されます。
守る。
( 2 ) プロトタイプ: 各 Beanリクエスト にインスタンスを提供します
( 3 ) request : 各ネットワーク リクエストのインスタンスを作成します。リクエストが完了すると、 Bean は 失敗し、ガベージ コレクターによって返されます。
受け取る。
( 4 ) session : リクエストスコープ と同様に、 セッションBeanのインスタンスが存在することを確認します。セッションの有効期限が切れた後、
その後、 Bean は 無効になります。
( 5 ) global-session : グローバル スコープ、 global-session は ポートレットアプリケーション に関連します アプリケーションがポートレットにデプロイされるとき
コンテナで作業する場合、コンテナには多数の ポートレットが含まれます すべての ポートレット に対してグローバル記憶変数を宣言する場合は、次のようにします。
次に、このグローバル変数を global-sessionに保存する必要があります グローバル スコープは、 Servlet セッションスコープと同じ効果があります
13. Spring がXML基づいてBean を 注入する 方法は何通りありますか?
( 1 )メソッドの注入 を設定します
( 2 ) コンストラクタインジェクション: ①indexを通じて パラメータの位置を設定します; ② typeを通じてパラメータの型を設定します
Ali 内部データ ( 3 ) 静的なファクトリ インジェクション。
( 4 ) インスタンスファクトリー。
通常、最初の 2 つは答えられますが、後の 2 つは苦手な人が多いので、知らない場合は言わないでください。そうしないと、知らないのかと聞かれるでしょう。
恥ずかしい。
14. Springフレームワークでは どのような デザイン パターンが使用されていますか?
これは比較的難しいトピックなので、デザイン パターンに戻るだけでなく、各デザイン パターンが Springで どのように使用されるかを理解する必要があります。
の。
単純なファクトリ パターン : Spring BeanFactory は 、単純なファクトリ パターンの具体化です。一意の識別子を渡して取得することによると、
Beanオブジェクト を取得します が、パラメータが渡された後に作成するか、パラメータが渡される前に作成するかは、特定の状況によって異なります。
ファクトリ モード : Spring FactoryBean は、 FactoryBeanインターフェイスのBean を実装する典型的なファクトリ メソッド モードです。
これは、 Factory と呼ばれる Bean のクラスです その特徴は、 Spring が getBean()呼び出しを 使用して Beanを取得するときに、自動的に
Bean getObject()メソッド 使用する と、返されるのは ファクトリ Bean ではなくbean.getOjbect()になります。
メソッドの戻り値。
シングルトン モード : Spring で使用されるシングルトン モードは次のとおりです: scope="singleton" 、登録されたシングルトン モード、 Bean は次 の場所に格納されます。
地図で Bean 名は キー として使用され Bean はとして使用されます
プロトタイプ モード : Spring で使用されるプロトタイプ モードは 、クローン作成によって生成された新しいプロトタイプを取得するたびに、 scope="prototype" になります。
インスタンスが変更されても、元のインスタンス オブジェクトには影響しません。
Iterator モード : Springには Iterator Iterableインターフェイス、およびIteratorインターフェイスを実装するCompositeIterator があります。
ポート。どちらも反復関連のインターフェイスです。 Iterableインターフェース が実装されているということは 、オブジェクトを反復できることを意味すると考えることができます。
世代的な。 Iteratorインターフェイスは、 Iteratorインターフェイス を実装するイテレータと同等であり 、反復可能オブジェクトを具体的に定義することと同等です。
オブジェクトを反復処理する方法。
プロキシ モード : Springの クラシック AOP は動的プロキシを使用して実装されます。動的プロキシは、 JDKCGlib動的プロキシ に分かれています
アダプター モード : Spring AOP AdvisorAdapterクラス 。これには 3 つの実装があります。
MethodBeforAdviceAdapter AfterReturnningAdviceAdapter ThrowsAdviceAdapter Spring
対応するアドバイスは、さまざまな AOP設定 に従って使用されます。戦略モードとは異なり、メソッドには複数のアドバイスを含めることができます。
アドバイス Adaptorで終わる スプリングは 多数あり 、そのほとんどはアダプター パターンです。
オブザーバー パターン : イベント リスナー 春の イベント: ApplicationEvent 、抽象クラスは継承します
EventObject クラスでは、 JDK はすべてのイベントが EventObject から継承することを推奨しています 春のイベントリスナー:
EventListenerインターフェース を継承する ApplicationListener 。JDK ではすべてのイベント リスナーが継承することをお勧めします。
イベントリスナー
テンプレート モード : Spring org.springframework.jdbc.core.JdbcTemplate は 非常に古典的なテンプレート モードです
アプリケーション (内の 実行メソッド) は 、アルゴリズムのステップ全体を定義します。
Ali内部データの 責任連鎖モード DispatcherServlet doDispatch()メソッド でリクエストに一致するプロセッサを取得
HandlerExecutionChain this.getHandler() 方法的处理使用到了责任链模式。
注意 :这里只是列举了部分设计模式,其实里面用到了还有享元模式、建造者模式等。可选择性的
回答,主要是怕你回答了迭代器模式,然后继续问你,结果你一问三不知,那就尴了尬了。
15 、说说 Spring ApplicationContext BeanFactory 的区
类图
包目录不同
spring-beans.jar org.springframework.beans.factory.BeanFactory
spring-context.jar org.springframework.context.ApplicationContext
国际化
BeanFactory 是不支持国际化功能的,因为 BeanFactory 没有扩展 Spring MessageResource
接口。相反,由于 ApplicationContext 扩展了 MessageResource 接口,因而具有消息处理的能力
( i18N )。
強力なイベントメカニズム ( Event )
基本的に、イベント ( Event ) の設計 に関しては、 ApplicationContext のイベント メカニズムであるオブザーバー モードと切り離すことはできません。
主に ApplicationEvent ApplicationListener の 2 つのインターフェイス、および Java スイング のイベントを通じて提供されます。
仕組みは同じです。つまり、イベントが ApplicationContextで発行されると、 ApplicationListener 拡張するすべての Bean
はこのイベントを受け取り、それに応じて処理します。
基盤となるリソースへのアクセス
ApplicationContext は 、複数のロードに使用できるResourceLoader (リソース ローダー) インターフェイス を拡張します。
Resource ですが、 BeanFactoryは ResourceLoader を拡張していません
Web アプリケーションのサポート
BeanFactoryは通常プログラムで作成されます ApplicationContext は 次を使用して宣言的に作成できます。
ContextLoader
もちろん ApplicationContext の実装メソッドの 1 つを使用して、プログラムで ApplicationContextを作成することもできます。
実例。
遅延読み込み
1. BeanFactroy は 遅延ロードを使用して Bean を注入します。つまり、特定の Bean が使用される 場合にのみ(呼び出し
getBean()) を実行する と、 Bean が ロードされてインスタンス化されます。この方法では、一部の既存の スプリング 構成を検出できません。
質問。逆に、 ApplicationContext はコンテナの起動時に すべての Bean を一度に作成します これ
このようにして、コンテナーが起動すると、 Spring で構成エラーを見つけることができます。
2. BeanFactory ApplicationContext は両方とも BeanPostProcessor をサポートします
BeanFactoryPostProcessorの使用 2 つの違いは次のとおりです。BeanFactory 手動で登録する必要がありますが、
ApplicationContext は自動的に登録されます。
ご覧のとおり、 ApplicationContext は BeanFactory を継承しており BeanFactoryはSpringでは比較的原始的です
Factoryは、 AOPWebなどのSpringプラグイン をサポートしません ApplicationContext にはBeanFactoryだけが含まれるわけではありませ
Spring のすべての機能、 Spring のさまざまなプラグインもサポート、フレームワーク指向の方法で動作し、コンテキストを階層化して実装します
現在も継承されています。
BeanFactory Springフレームワーク のインフラストラクチャであり、 Spring 自体を指向していますが、 ApplicationContext は使用を指向しています。
Spring 開発者は、ほとんどすべての場合に直接使用できる BeanFactoryよりも 実用的なアプリケーション指向の関数を提供します。
基礎となるBeanFactoryの代わりに ApplicationContext を 使用します
共通コンテナ
BeanFactory 型にはXmlBeanFactory があり 対応するものを作成できます。
ApplicationContext タイプの一般的なコンテナは次のとおりです。
1. ClassPathXmlApplicationContext : ClassPath XML構成ファイル からコンテキストを読み取り 、上記を生成します。
以下に定義します。アプリケーション コンテキストはプログラム環境変数から取得されます。
2. FileSystemXmlApplicationContext : コンテキストは、 ファイル システム内の XML構成ファイルから読み取られます
3. XmlWebApplicationContext : Webアプリケーション XMLファイルから コンテキストを読み取ります。たとえば、 Spring MVCでは
使用事例。
16. Springフレームワーク スレッドのシングルトンBean は安全 ですか ?
Springフレームワークは、 シングルトン Bean のマルチスレッド カプセル化を実行しません。
シングルトンBean のスレッド セーフティと同時実行性の問題については 、開発者が自分で解決する必要があります。
シングルトンのスレッド安全性の問題は、 Spring が 考慮すべきことではありません。 Spring がすべきことは以下を提供することです
単一 Bean または複数 Beanを構築する機能
Ali の内部情報 もちろんですが、実際には、ほとんどの Spring Bean は 可変状態を持たないため、ある程度 Spring のシングルトン
Bean は スレッドセーフです。 Bean に複数の状態がある場合は 、スレッドの安全性を自分で確保する必要があります。最も明白な解決策
その方法は、多態性 Beanの スコープ( Scope )を Singleton から Prototypeに変更することです
17. Spring は循環依存関係を どのように解決しますか?
全体のプロセスは大まかに次のとおりです。
1. まず 、A は 初期化の最初のステップを完了し、 事前に自分自身を公開します ( ObjectFactoryを通じて 事前に自分自身を公開します)。
初期化中に、オブジェクトB に依存していることがわかったので、この時点でget(B) を 試みましたが B がまだ作成されていないことがわかりました。
出てくる;
2. 次に、 B は 作成プロセスを実行しますが、 Bが初期化されると、 B が Cに依存しておりC がまだ作成されていないこと がわかります。
3. この時点で、 C は初期化プロセスを再度開始しますが、 初期化プロセス中に Cが Aに依存していることが判明したため、 get(A) を 試行します これ
このとき、 A はキャッシュに追加されているため(通常は 3 次キャッシュの singletonFactoriesに追加されます )、
ObjectFactory は 事前に公開されているため、 Aオブジェクトは ObjectFactory#getObject() メソッドを通じて取得できます Cテイク
A 对象后顺利完成初始化,然后将自己添加到一级缓存中;
4. 回到 B B 也可以拿到 C 对象,完成初始化, A 可以顺利拿到 B 完成初始化。到这里整个链路
就已经完成了初始化过程了。
关键字:三级缓存,提前曝光。
18 、说说事务的隔离级别
未提交读 (Read Uncommitted) :允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
提交读 (Read Committed) :只能读取到已经提交的数据。 Oracle 等多数数据库默认都是该级别 (
重复读 )
阿里内部资料 可重复读 (Repeated Read) :在同一个事务内的查询都是事务开始时刻一致的, Mysql InnoDB
认级别。在 SQL 标准中,该隔离级别消除了不可重复读,但是还存在幻读(多个事务同时修改同一
条记录,事务之间不知道彼此存在,当事务提交之后,后面的事务修改的数据将会覆盖前事务,前
一个事务就像发生幻觉一样)
Serializable (Serializable) : 完全にシリアル化された読み取り。各読み取りはテーブル レベルの共有ロックを取得する必要があり、読み取りと書き込みは相互にブロックされます。
ノンリピータブルリードとファントムリードの違いは主に次のとおりです。ノンリピータブルリードを解決するには、現在条件を満たしているレコードをロックする必要がありますが、ファントムリードを解決するには、次のことが必要です。
現在のレコードおよび条件を満たす類似のレコードをロックします。たとえば、商品の情報をクエリする場合、反復読み取りトランザクション分離レベルは次のようになります。
反復不可能な読み取りを解決するために、現在の製品情報がロックされていることを確認します。ただし、製品の数がカウントされる場合、途中にレコードが挿入され、繰り返し読み取ることができます。
トランザクション分離レベルでは、2 つのトランザクションの統計数が同じであることは保証できません。
19. トランザクションのコミュニケーションレベルについて話す
Spring トランザクションは、次 の 7 つの 伝播メカニズムを定義します。
1. PROPAGATION_REQUIRED: デフォルトの Spring トランザクション伝播レベル。現在のトランザクションがある場合は、トランザクションに参加します。
トランザクションがない場合は、新しいトランザクションを作成します。
2. PAOPAGATION_REQUIRE_NEW: 現在のトランザクションがない場合は、新しいトランザクションを作成します。現在トランザクションが存在する場合は、新しいトランザクションを作成します
1 つのトランザクション内で、古いトランザクションと新しいトランザクションは互いに独立しています。外部トランザクションによってスローされた例外のロールバックは、内部トランザクションの通常の送信には影響しません。
3. PROPAGATION_NESTED: 現在のトランザクションが存在する場合、現在のトランザクション内でネストされ、実行されます。現在取引が無い場合は、
次に、 REQUIRE_NEW と同様の新しいトランザクションを作成します
4. PROPAGATION_SUPPORTS: 現在のトランザクションをサポートします。現在のトランザクションがない場合は、非トランザクション方式で実行されます。
5. PROPAGATION_NOT_SUPPORTED: 非トランザクション方式で実行します。現在のトランザクションがある場合は、現在のトランザクションを一時停止します。
上昇。
6. PROPAGATION_MANDATORY: トランザクションの実行は必須です。現在のトランザクションがない場合、例外がスローされます
7. PROPAGATION_NEVER: 非トランザクション方式で実行します。現在のトランザクションが存在する場合、例外がスローされます。
通常、 Spring トランザクションの伝播レベルは定義する必要はなく、 ネストされたトランザクションの場合を除き、デフォルトは PROPAGATION_REQUIREDです。
状況に焦点を当てる必要がある。
20. Spring トランザクション の実装
プログラムによるトランザクション管理: これは、トランザクションをプログラムで管理できることを意味し、柔軟性が非常に高くなりますが、
維持が難しい。
宣言型トランザクション管理: このアプローチは、トランザクション管理をビジネス コードから分離できることを意味します。 注釈またはXML を渡すだけで済みます
管理トランザクションを構成します。
Ali 内部情報 21. Springフレームワークのトランザクション管理の利点は 何ですか
さまざまなトランザクション API ( JTA、JDBC、Hibernate、JPA、JDO など )に統一されたプログラミング モデルを提供します。プログラムによるトランザクション
管理は、 一連の複雑なトランザクションAPI ( JTAなど) ではなく、単純な APIを提供し、 宣言型トランザクション管理をサポートします。それは可能です
Spring のさまざまなデータ アクセス テクノロジは適切に統合されています。
さまざまなトランザクション API ( JTA、JDBC、Hibernate、JPA、JDO など )に統一されたプログラミング モデルを提供します。プログラムによるトランザクション
管理は、 一連の複雑なトランザクションAPI ( JTAなど) ではなく、単純な APIを提供し、 宣言型トランザクション管理をサポートします。それは可能です
Spring のさまざまなデータ アクセス テクノロジは適切に統合されています。
さまざまなトランザクション API ( JTA、JDBC、Hibernate、JPA、JDO など )に統一されたプログラミング モデルを提供します。プログラムによるトランザクション
管理は、 一連の複雑なトランザクションAPI ( JTAなど) ではなく、単純な APIを提供し、 宣言型トランザクション管理をサポートします。それは可能です
Spring のさまざまなデータ アクセス テクノロジは適切に統合されています。
22. ビジネスの 3 つの要素とは何ですか?
データ ソース : MySQL など、トランザクションの実際のプロセッサである特定のトランザクション リソースを示します
トランザクション マネージャー : 大きなハウスキーパーのように、オープン、コミット、ロールバックなど、トランザクション全体の処理を管理します。
トランザクション アプリケーションと属性の構成 : トランザクションに参加するメソッド、トランザクションに参加する方法、およびいくつかの関連属性を示す識別子のようなもの
分離レベル、タイムアウト期間などのプロパティ。
23. トランザクション アノテーションの本質は何ですか?
@Transactional アノテーションは、実行時にトランザクション インフラストラクチャによって読み取られ、キャンセルされる一部の (トランザクション関連) メタデータにすぎません。
このメタデータを使用して Bean のトランザクション動作を 設定 ます 一般に、これには 2 つの機能があります。1 つはメソッドが参照する必要があることを示すことです。
トランザクションの 2 番目は、関連する属性を設定して、トランザクションの参加方法と操作動作をカスタマイズすることです。
宣言的トランザクションは主にSpring AOP によるものです トランザクション インターセプタを使用して、メソッド呼び出しの前後 または前後で トランザクションを可能にします。
トランザクションの完了を促進するための機能強化 ( アドバイス)。
@Transactional アノテーションは、クラスとメソッドの両方にマークできます。クラスの場合、デフォルトはすべてに適用されます
やり方がある。このときメソッドもマークされている場合は、そのメソッドの優先度が高くなります。また、メソッドは publicである必要があることにも注意してください
MyBatisの 記事
1.MyBatis
( 1 ) Mybatis は、 JDBC を内部でカプセル化する ORM (オブジェクト リレーショナル マッピング) フレームワークであり、 開発時にSQLのみに注意する必要があります。
ステートメント自体は、ドライバーのロード、接続の作成、 ステートメントの作成 などの複雑なプロセスを処理するためにエネルギーを費やす必要はありません。プログラマーストレート
そして、独自のエコロジカル SQLを作成すると、 SQL の実行パフォーマンスを 厳密に制御でき 、柔軟性が高くなります。
Ali 内部情報 ( 2 ) MyBatis は、 XMLまたはアノテーション を使用して ネイティブ情報を構成およびマッピングし、POJO をデータベース内のレコードにマッピングし、
ほぼすべての JDBC コードを排除し、手動でパラメータを設定して結果セットを取得します。
( 3 ) XML ファイルまたはアノテーションを通じて実行されるさまざまな ステートメントを 構成し、 Java オブジェクトと
statement sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果
映射为 java 对象并返回。(从执行 sql 到返回 result 的过程)。
2 、说说 MyBatis 的优点和缺点
优点:
1 )基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响, SQL
XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并
可重用。
2 )与 JDBC 相比,减少了 50% 以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连
接;
( 3 ) さまざまなデータベースとの互換性が高い ( MyBatis は データベースへの接続にJDBC を使用するため、 JDBCでサポートされているデータであれば可能です)
MyBatisがサポートする ライブラリ )。
( 4 ) Springとうまく統合 できます。
( 5 ) マッピング タグを提供し、 オブジェクトとデータベース間の ORMフィールド関係マッピングをサポートします。オブジェクト リレーショナル マッピング タグを提供し、オブジェクトをサポートします。
関係コンポーネントのメンテナンス。
欠点がある
( 1 ) SQLステートメントを作成する作業負荷は、特にフィールドが多く、関連するテーブルが多数ある場合に比較的大きくなり、開発者の SQLステートメント を作成する能力に悪影響を及ぼします。
尋ねなければなりません。
( 2 ) SQL 文がデータベースに依存しているため、データベースの移植性が悪く、データベースを自由に置き換えることができません。
3. #{}${}の違いは何 ですか ?
#{} はプリコンパイル処理、 ${} は文字列置換です。
Mybatis 在处理 #{} 时,会将 sql 中的 #{} 替换为 ? 号,调用 PreparedStatement set 方法来赋值;
Mybatis 在处理 ${} 时,就是把 ${} 替换成变量的值。
使用 #{} 可以有效的防止 SQL 注入,提高系统安全性。
4 、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?
1 种:
通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
阿里内部资料 <select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”>
select order_id id, order_no orderno ,order_price price form orders where
order_id=#{id};
</select>
2 种:
通过来映射字段名和实体类属性名的一一对应的关系。
<select id="getOrder"parameterType="int" resultMap="orderresultmap">
order_id=#{id} の注文から * を選択
</選択>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!– id属性を 使用して 主キー フィールドをマップします– >
<id property=”id” column=”order_id”>
<!– result属性を 使用して 非主キー フィールドをマップします。propertyエンティティ クラスの属性名、columnはデータ テーブルの属性です–>
<結果プロパティ = “orderno” カラム =”order_no”/>
<結果プロパティ=”価格” 列=”注文価格” />
</reslutマップ>
5. Mybatis は どのように ページネーションを行うのですか? ページネーションプラグインの原理は何ですか?
Mybatis は ページングにRowBoundsオブジェクト を使用します。これは、物理的なパーティショニングではなく、 ResultSet結果セットに対して実行されるメモリ ページングです。
ページ。 SQL で物理ページングを使用してパラメーターを直接指定して物理ページング関数を完成させることも、ページング プラグインを使用して物理ページング関数を完成させることもできます。
ページネーションを管理します。例: MySQLデータ の場合、元の SQLの後の スペル 制限
ページング プラグインの基本原理は、 Mybatisが提供するプラグイン インターフェイスを使用し てカスタム プラグインを実装し、プラグイン インターセプト メソッドでそれをインターセプトすることです。
SQL を実行し その SQLを書き換えて 方言に従って 対応する物理ページング ステートメントと物理ページング パラメータを追加します。
6. Mybatis は どのように SQL実行結果をターゲット オブジェクトにカプセル化して返しますか? もつ
どのマッピング形式ですか?
1 つ目は、タグを使用して、データベースの列名とオブジェクトの属性名の間のマッピング関係を 1 つずつ定義する方法です。
2 つ目は、 SQL列の alias 関数 を使用して、 列の別名をオブジェクト属性名として書き込む方法です。
カラム名と属性名のマッピング関係により、 Mybatis は リフレクションによってオブジェクトを作成すると同時に、リフレクションを使用してオブジェクトに属性を 1 つずつ割り当てます。
値と戻り値、マッピング関係が見つからない属性には割り当てることができません。
7. バッチ挿入を実行するにはどうすればよいですか?
まず 単純な 挿入 ステートメントを作成します
Ali の内部情報 <insert id="insertname">
名前 (name) 値 (#{value}) に挿入
</挿入>
次に、 Javaコード で次のようにバッチ挿入を実行します
list<string> 名 = new arraylist();
names.add(“フレッド”);
names.add(“バーニー”);
names.add(“ベティ”);
names.add(“ウィルマ”);
// ここに注意してください executortype.batch
sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
試す {
namemapper マッパー = sqlsession.getmapper(namemapper.class);
for (文字列名 : 名前) {
マッパー.挿入名(名前);
}
sqlsession.commit();
}catch(例外 e){
e.printStackTrace();
sqlSession.rollback();
eを投げます。
}
ついに {
sqlsession.close();
}
8. XMLマッピング ファイル 内で 、一般的なselect|insert|updae|deleteを除く
タグ以外にはどのようなタグがありますか?
動的sql 9 つの タグ( SQL フラグメント タグを含む) を追加し、タグを通じて SQL フラグメントを導入し、自動インクリメントをサポートしない主キーの戦略を生成します。
ラベルを省略します。
9. MyBatis は1 対 1 を実装する方法が 何通りありますか ?どのように機能しますか?
結合クエリとネストされたクエリがあります 結合クエリは複数のテーブルの結合クエリです 一度だけクエリされ resultMap 設定されます。
アソシエーション ノードは 1 対 1 のクラスで構成できます。
ネストされたクエリは、最初にテーブルをチェックし、次にこのテーブルの結果の外部キー ID に従って 別のテーブルのデータをクエリします
アソシエーション 構成ですが、別のテーブルのクエリは select 属性を通じて構成されます。
Ali の内部情報 10. Mybatis は遅延読み込みをサポートしてい ますか? サポートされている場合、その実装原理は何ですか
何?
Mybatis は、 アソシエーションオブジェクトコレクションオブジェクトの遅延読み込み のみをサポートし ます
まず、 コレクションと は 1 対多のクエリを指します。 Mybatis設定ファイル では 、遅延読み込みを有効にするかどうかを設定できます。
LazyLoadingEnabled=true|false
その原理はCGLIB を使用して ターゲット オブジェクトのプロキシ オブジェクトを作成することです。ターゲット メソッドが呼び出されると、インターセプタ メソッドに入ります。
a.getB().getName() を使用すると 、インターセプターの invoke() メソッドは a.getB()が null値 であることを検出し 、事前に保存された値を個別に送信します。
B objectに関連付けられた SQL を クエリし B をクエリして、 a.setB(b)を呼び出します 。これにより、 オブジェクト aの b属性に値が設定され、完了します。
a.getB().getName() メソッド呼び出し。これが遅延読み込みの基本原則です。
もちろん、 Mybatisだけでなく、 Hibernate を含むほとんどすべてのものが、 遅延読み込みをサポートするという同じ原則を持っています。
11. Mybatisのキャッシュ メカニズム について話します
マイバティス 全体:
レベル 1 キャッシュ localCache
アプリケーションの実行中、 1 つのデータベース セッションでまったく同じクエリ条件を使用して SQL を複数回実行することがあります
MyBatis は、シーンのこの部分を最適化するためのレベル 1 キャッシュ ソリューションを提供しており、同じ SQLステートメント であれば 、最初にレベル 1 キャッシュにヒットします。
パフォーマンスを向上させるために、データベースに直接クエリを実行することは避けてください。
Ali の内部情報によると、 SqlSession は Executor を 保持し 、各Executor はLocalCacheを持ちますユーザーがクエリを開始すると、
MyBatis は、 現在実行されているステートメントに基づいて MappedStatementを生成し、 それをローカル キャッシュ 内でクエリします。
存在する場合は、結果をユーザーに直接返します。キャッシュがヒットしない場合は、データベースにクエリを実行し、結果を Local Cacheに書き込み 、最後に
結果をユーザーに返します。特定の実装クラスのクラス関係図を次の図に示します。
1. MyBatis 一级缓存的生命周期和 SqlSession 一致。
2. MyBatis 一级缓存内部设计简单,只是一个没有容量限定的 HashMap ,在缓存的功能性上有
所欠缺。
3. MyBatis 的一级缓存最大范围是 SqlSession 内部,有多个 SqlSession 或者分布式的环境下,
数据库写操作会引起脏数据,建议设定缓存级别为 Statement
二级缓存
在上文中提到的一级缓存中,其最大的共享范围就是一个 SqlSession 内部,如果多个 SqlSession
之间需要共享缓存,则需要使用到二级缓存。开启二级缓存后,会使用 CachingExecutor 装饰
Executor ,进入一级缓存的查询流程前,先在 CachingExecutor 进行二级缓存的查询,具体的工作
流程如下所示。
阿里内部资料 二级缓存开启后,同一个 namespace 下的所有操作语句,都影响着同一个 Cache ,即二级缓存被
多个 SqlSession 共享,是一个全局的变量。
当开启缓存后,数据的查询执行的流程为:
二级缓存 -> 一级缓存 -> 数据库
1. MyBatis 的二级缓存相对于一级缓存来说,实现了 SqlSession 之间缓存数据的共享,同时粒度
更加细,能够到 namespace 级别,通过 Cache 接口实现类不同的组合,对 Cache 的可控性
也更强。
2. MyBatis 在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件
比较苛刻。
3. 在分布式环境下,由于默认的 MyBatis Cache 实现都是基于本地的,分布式环境下必然会出现
读取到脏数据,需要使用集中式缓存将 MyBatis Cache 接口实现,有一定的开发成本,直
接使用 Redis Memcached 等分布式缓存可能成本更低,安全性也更高。
12 JDBC 编程有哪些步骤?
1. 装载相应的数据库的 JDBC 驱动并进行初始化:
2. JDBCとデータベースの間にConnection接続 を確立します
クラス forName ( "com.mysql.jdbc.Driver" );
接続 c = DriverManager getConnection ( "jdbc:mysql://127.0.0.1:3306/test?
CharacterEncoding=UTF-8" , "root" , "123456" );
Ali 内部情報 3. StatementまたはPreparedStatementインターフェイス を作成し、 SQLステートメントを実行します。
4. 結果を処理して表示します。
5. リソースを解放します。
13. MyBatisで どのような デザイン パターンを見ましたか?
14.たとえば MyBatis UserMapper.java は インターフェイスですが、なぜ実装がないのですか?
現在のクラスを引き続き呼び出すことはできますか?
JDK 動的プロキシ + MapperProxy を使用します 基本的に、 MapperProxy invokeメソッド は と呼ばれます
WeChat パブリック アカウントにご注目ください: Java バックエンド テクノロジのフルスタック
スプリング ブーツ
1. SpringBoot を 使用する理由
Spring Boot に は次のような多くの利点があります。
1. 独立動作
Spring Bootには、 Tomcat Jettyなどの さまざまな サーブレット コンテナーも埋め込まれています。 これで、 warパッケージにパッケージ化してコンテナーにデプロイする必要がなくなりました。
このうち、 Spring Boot は、実行可能な jarパッケージにパッケージ化されており、依存するすべてのパッケージがjarパッケージ内にある 限り、独立して実行できます
2. 構成の簡素化
spring-boot-starter-web スターターは他のコンポーネントに自動的に依存するため、 Maven 構成が簡素化されます。3. 自動構成
Ali 内部情報 Spring Boot は、 現在のクラスパスの下のクラスおよび jarパッケージに従って Bean を 自動的に構成できます ( spring-boot-starter の追加など)。
Webイネーブラーは Webの機能 を持つことができ 、他の構成は必要ありません。
4. コード生成と XML 構成は不要
Spring Boot 構成プロセスではコード生成が行われず、すべての構成作業は XML構成ファイルなしで 完了できます。これらのファイルはすべて XML 構成ファイルに基づいています。
これは、 Spring4.xのコア機能の 1 つ でもある条件付きアノテーションで完成します
5. アプリケーションの監視
Spring Boot は、 サービスとアプリケーションを監視し、ヘルスチェックを実行するための一連のエンドポイントを提供します。
2. Spring Bootのコアとなるアノテーションは どれですか ? 主にどのような注釈で構成されていますか
の?
スタートアップ クラスの上のアノテーションは @SpringBootApplicationで 、これは Spring Bootのコア アノテーションでも あります。
以下の 3 つの 注釈:
@SpringBootConfiguration : @Configuration アノテーションを組み合わせて設定ファイルの機能を実現します。
@EnableAutoConfiguration : 自動構成機能をオンにします。また、データをオフにするなどの自動構成オプションをオフにすることもできます。
ソース自動構成関数によると: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class
})
@ComponentScan : Spring コンポーネントのスキャン。
3. Spring Boot を実行するには どのような方法がありますか?
1 ) コマンドを使用してパッケージ化するか、コンテナーで実行します
2 ) Maven/Gradleプラグイン で実行
3 ) main メソッドを直接実行して実行します。
4. Spring Bootスターターを 理解するにはどうすればよいですか ?
スターター とは:
スターターは 、アプリケーションに統合できる一連の依存関係パッケージを含むスターターとして理解でき、ワンストップで統合できます。
Spring やその他のテクノロジを使用できるため、サンプル コードや依存パッケージをどこでも見つける必要がなくなります。 Spring JPA を 使用して データベースにアクセスする場合は、次のようにします。
spring-boot-starter-data-jpa スターター依存関係 を追加すると、それを使用できるようになります。 スターターには、 使用する必要がある多くのプロジェクトが含まれています
依存関係は、迅速かつ継続的に実行され、サポートされる一連の管理された推移的な依存関係です。
スターター の名前:
Ali の内部情報によると、 Spring Boot の公式スターターはすべて、特定のアプリケーション タイプを表す spring-boot-starter-にちなんで命名されています 三番目
Fang のスターターには spring-bootで 始まる名前を付けることはできません。それらはすべて Spring Bootによって公式に予約されています 通常、第三者は次のことを行う必要があります。
mybatis mybatis-spring-boot-starter の ように、このように名前が付けられます
スターター カテゴリー:
1. Spring Boot アプリケーション クラス スターター
1. Spring Boot プロダクションスターター
1. Spring Boot テクノロジー スターター
1. 他のサードパーティ製ランチャー
5. Spring Bootの起動時に特定のコードを実行する にはどうすればよいですか?
如果你想在 Spring Boot 启动的时候运行一些特定的代码,你可以实现接口 ApplicationRunner
CommandLineRunner ,这两个接口实现方式一样,它们都只提供了一个 run 方法。
CommandLineRunner :启动获取命令行参数
6 Spring Boot 需要独立的容器运行吗?
阿里内部资料 可以不需要,内置了 Tomcat/ Jetty 等容器。
7 Spring Boot 中的监视器是什么?
Spring boot actuator spring 启动框架中的重要功能之一。 Spring boot 监视器可帮助您访问生产
环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些
外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作
HTTP URL 访问的 REST 端点来检查状态。
8 、 如何使用 Spring Boot 实现异常处理?
Spring 提供了一种使用 ControllerAdvice 处理异常的非常有用的方法。 我们通过实现一个
ControlerAdvice 类,来处理控制器类抛出的所有异常。
9 、 你如何理解 Spring Boot 中的 Starters
Starters 可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成
Spring 及其他技术,而不需要到处找示例代码和依赖包。如你想使用 Spring JPA 访问数据库,只要
加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。
10 springboot 常用的 starter 有哪些
spring-boot-starter-web 嵌入 tomcat web 开发需要 servlet jsp 支持
spring-boot-starter-data-jpa 数据库支持
spring-boot-starter-data-redis redis データベースのサポート
spring-boot-starter-data-solr solr サポート
mybatis-spring-boot-starter サードパーティの mybatis 統合 スターター
11. SpringBoot がホット デプロイメント を実装する 方法は何通りありますか?
主に次の 2 つの方法があります。
スプリング式
Spring-boot-devtools
12. Spring Boot設定の読み込み順序 を理解するにはどうすればよいですか ?
Spring Boot では 、次のメソッドを使用して構成をロードできます。
1 ) プロパティ ファイル。
2 ) YAML ファイル。
Ali 内部情報 3 ) システム環境変数。
4 ) コマンドラインパラメータ。
待ってください ...
13. Spring Bootのコア構成ファイルは 何ですか? 違いはなんですか
何?
Spring Boot のコア構成ファイルは、 アプリケーション構成ファイル ブートストラップ 構成ファイルです。
アプリケーション 構成ファイルは理解しやすく、主に Spring Boot プロジェクトの自動構成に使用されます。
ブートストラップ 構成ファイルには次のアプリケーション シナリオがあります。
Spring Cloud Config構成センター を使用する場合、ブートストラップ構成ファイル内の構成に接続を追加する 必要があります。
センターの構成プロパティは、外部構成センターの構成情報をロードするために使用されます。
オーバーライドできない一部の固定プロパティ。
いくつかの暗号化 / 復号化シナリオ。
14. Spring BootActiveMQ を統合するにはどうすればよいです か?
Spring Boot ActiveMQ を統合するには、spring-boot-starter-activemq依存関係 を使用します それはただ必要です
必要な構成はほとんどなく、定型コードも必要ありません。
MySQL の記事
1. データベースの 3 つのパラダイムとは何ですか
第 1 正規形: 列をさらに分割することはできない 第 2 正規形: 行を一意に区別できる、主キー制約がある 第 3 正規形: テーブルの非主属性に依存できない
他のテーブルの非主属性外部キー制約と 3 つの正規形は 1 つのレベルと 1 つのレベルに依存します。第 2 正規形は第 1 正規形に基づき、第 3 正規形は第 3 正規形に基づいています。
第 1 正規形と第 2 正規形を確立します。
2. MySQLデータベース エンジンとは 何ですか ?
mysql が提供するすべてのストレージ エンジンを表示する方法
mysql> エンジンを表示;
Alibaba 内部データ mysql で 一般的に使用されるエンジンには、 MYISAM Innodb Memory MERGEが含まれます。
MYISAM : フルテーブルロック、高い実行速度、トランザクションをサポートしない、外部キーをサポートしない、同時実行パフォーマンスが低い、スペースを占有する
これは比較的小さく、トランザクションの整合性の要件はありません。基本的に、 select および insert ベースのアプリケーションはこのエンジンを使用できます。
Innodb: 行レベルのロック、コミット、ロールバック、およびクラッシュ回復機能によるトランザクション セキュリティを提供し、自動拡張カラムをサポートし、
外部キー制約、強力な同時実行性、 MYISAM 2.5倍のスペースを占有 、比較的低い処理効率
メモリ: フルテーブルロック、コンテンツに保存され、高速ですが、データ量に比例してメモリスペースを占有し、データは
mysqlを再起動すると失われます。デフォルトでは HASHインデックス が使用され、検索効率は非常に高いですが、精密な検索には適していません。主に次の目的で使用されます。
内容があまり変更されないコードテーブル
MERGE : MYISAMテーブルの セットの組み合わせです
3. InnoDBMyISAMの違い について話す
1. InnoDB は トランザクションをサポートしますが、 MyISAM はサポート しません。 InnoDBの場合、 SQL ステートメントはデフォルトでトランザクションにカプセル化され、
コミット。これは速度に影響するため、トランザクションを形成するには 開始コミットの間に複数の SQL 言語を入れるのが最善です
2. InnoDB は 外部キーをサポートしますが、 MyISAM はサポートしません。外部キーを含む InnoDB テーブルを MYISAMに変換すると 失敗します。
3. InnoDB はクラスター化インデックスであり、データ ファイルはインデックスに関連付けられているため、主キーが必要であり、主キーによるインデックス作成の効率は非常に高くなります。
ただし、補助インデックスには 2 つのクエリが必要です。最初に主キーがクエリされ、次に主キーを介してデータがクエリされます。したがって、主キーは使用しないでください。
大きすぎます。主キーが大きすぎるため、他のインデックスも大きくなります。MyISAM 非クラスター化インデックスであり、データ ファイルは分離されており、
インデックスはデータ ファイルへのポインタを保持します。主キーインデックスと副キーインデックスは独立しています。
4. InnoDB は テーブル内の特定の行数を保存せず、 select count(*) from tableを実行する ときにテーブル全体のスキャンを必要とします。 MyISAM が 使用する
変数はテーブル全体の行数を保存します。上記のステートメントを実行するときは、変数を読み取るだけでよく、速度は非常に高速です。
5. Innodb は フルテキスト インデックス作成をサポートしませんが、 MyISAM は フルテキスト インデックス作成をサポートしており、 MyISAM の方がクエリ効率が高くなります。
4. データベーストランザクション
トランザクションとは何ですか? :
複数の SQL ステートメント。すべて成功するかすべて失敗します。
アリババの内部データトランザクション の特徴:
データベーストランザクションの特性: 原子性 (Atomic) 、一貫性 (Consistency) 、分離 (Isolation) 、永続性
(耐久性) 略して ACID
原子性: トランザクションを構成する複数のデータベース操作は、すべての操作が成功した場合に限り、分割できない原子単位になります。
トランザクション全体がコミットされます。いずれかの操作が失敗した場合は、データベースを元の状態に戻すために、実行されたすべての操作を元に戻す必要があります。
州。
一貫性: トランザクション操作が成功した後、データベースの状態はビジネス ルールと一致します。つまり、データは破壊されません。
たとえば、 A が Bに100元を 送金した場合 、操作が成功したかどうかに関係なく、ABの口座の合計金額は変わりません。
分離: 同時データ操作中、異なるトランザクションは独自のデータ空間を持ち、それらの操作は互いに干渉しません。
乱す
永続性: トランザクションが正常にコミットされると、トランザクション内のすべての操作をデータベースに永続化する必要があります。
5. インデックスとは
公式導入インデックスは、 MySQL が効率的に データ を取得するのに役立つ データ構造です。より一般的に言えば、データベースのインデックスは本のようなものです。
以前のディレクトリにより、 データベースのクエリ速度が向上します
一般に、インデックス自体も非常に大きく、すべてをメモリに保存することは不可能であるため、 インデックスはディスク上のファイルに保存されることがよくあります。
( 別のインデックス ファイルに保存することも、データと一緒にデータ ファイルに保存することもできます)。
通常参照するインデックスには、クラスター化インデックス、カバリング インデックス、複合インデックス、プレフィックス インデックス、一意インデックスなどが含まれます。
説明は省略しますが、デフォルトでは、 B+ ツリー構造 (多方向検索ツリー、必ずしもバイナリである必要はありません) によって編成されたインデックスが使用されます。
6. SQL の最適化方法には どのようなもの がありますか?
1.クエリ ステートメントでは select * を使用しないでください。
2. サブクエリを最小限に抑え、代わりに関連付けクエリ ( 左結合、右結合、内部結合 )を使用します。
3. INまたはNOT IN の使用を減らし、代わりに 存在する存在しない、または関連するクエリ ステートメントを使用します。
4. orクエリは可能な限りUnionまたはUnion allに置き換えます(重複データがないことを確認する場合、または重複データを削除する必要がある場合は
すべてを結合したほう が良いでしょう
5. where句では!=または<>演算子を使用し ないようにしてください。使用しないと、エンジンはインデックスの使用を断念し、テーブル全体のスキャンを実行します。
6. where句でフィールドのnull値を判断 しないようにしてください 。そうしないと、エンジンがインデックスの使用を断念し、テーブル全体を実行することになります。
次のようなスキャン: select id from t where num is null を実行すると、テーブルに num列が存在しないようにnumにデフォルト値0を設定 できます。
null 値の場合は、次のようにクエリします: select id from t where num=0
7. drop delete truncateの違い について簡単に説明します
SQL drop delete 、および truncate は すべて削除を意味しますが、この 3 つの間にはいくつかの違いがあります。
Ali の内部データの 削除 切り捨ては 、テーブルの構造速度を削除することなく 、テーブルのデータのみを削除します。 一般的に言えば 、drop> truncate >delete delete
ステートメントは dml であり、この操作は ロールバック セグメント 配置され トランザクションが送信された後に有効になります。対応するトリガーがある場合は、実行されます。
これは、truncate、drop ddl の場合にトリガーされ、 操作はすぐに有効になり 、元のデータは ロールバック セグメント 置かれず ロールバックできません
この操作では トリガーはトリガーされません。
8. ビューとは何ですか
ビューは、物理テーブルと同じ機能を持つ仮想テーブルです。ビューに対して追加、変更、確認、操作を行うことができます。通常、その試みは次のとおりです。
1 つまたは複数のテーブルの行または列のサブセット。ビューを変更しても、基になるテーブルには影響しません。データの取得が容易になりますので、
複数テーブルのクエリと比較します。
9. 内部結合、左外部結合、右外部結合とは何ですか?
内部結合 ( Inner Join ): 2 つのテーブル 内の関連するレコードを照合します。
左外部結合 ( 左外部結合): 2 つのテーブル内の関連レコードの 照合に加えて、左側の テーブルの残りのレコードとも照合します。
レコードでは、右側のテーブル内の一致しないフィールドは NULLで表されます
右外部結合 ( 右外部結合): 2 つのテーブル内の関連レコードの 照合に加えて、右側の テーブル内の残りのレコードとも照合します。
レコードでは、左側のテーブル内の一致しないフィールドは NULLで表されます 左のテーブルと右のテーブルを判断するときは、テーブル名に従って 外部結合に表示される必要があります。
左右の位置関係。
10. 同時トランザクションによって引き起こされる問題は何ですか ?
一般的なアプリケーションでは、複数のトランザクションが同時に実行され、タスク (複数のユーザー) を完了するために同じデータを操作することがよくあります。
同じデータを操作します)。同時実行性は必要ですが、次のような問題が発生する可能性があります。
ダーティ リード ( ダーティ リード ) : トランザクションがデータにアクセスしてデータを変更しており、この変更が言及されていない場合
データベースに引き渡されると、この時点で別のトランザクションもデータにアクセスし、データを使用します。なぜなら、このデータは、
データがコミットされていない場合、別のトランザクションによって読み取られたデータは ダーティ データ 」であり ダーティ データ 」に基づく 操作は可能です。
間違っている可能性があります。
変更の喪失 ( 変更の喪失 ) : トランザクションがデータを読み取るときに、別のトランザクションもそのデータにアクセスすることを指します。
データによれば、最初のトランザクションでデータが変更された後、2番目のトランザクションでもデータが変更されます。最初のトランザクション
ファイルの変更結果が失われるため、変更の喪失と呼ばれます。例: トランザクション 1 は テーブル内のデータ A=20を読み取り 、トランザクション 2 も読み取ります。
A=20 を読み取り 、トランザクション 1 は A=A-1 を変更し 、トランザクション2もA=A-1を変更します。最終結果はA=19で、トランザクション1の変更は失われます。
Unrepeatable read ( Unrepeatableread ) : トランザクション内で同じデータを複数回読み取ることを指します。この取引はまだ完了していません
最後に、別のトランザクションもデータにアクセスします。次に、最初のトランザクションの 2 つの読み取りの間に、2 番目のトランザクションが発生するため、
最初のトランザクションを変更すると、最初のトランザクションによって 2 回読み取られたデータが異なる可能性があります。これは、1 つのトランザクションでデータが 2 回読み取られた場合に発生します。
データが異なるため、Non-Repeatable Read と呼ばれます。
ファントム読み取り ( ファントム読み取り ) : ファントム読み取りは、非反復読み取りと似ています。トランザクション ( T1 ) が数行を読み取るときに発生します。
データを挿入した後、別の同時トランザクション ( T2 ) がデータを挿入します。後続のクエリでは、最初のトランザクション ( T1 ) が
もともと存在しなかった記録をさらにいくつか見つけると、幻覚があるように見えるため、ファントムリーディングと呼ばれます。
ノンリピータブルリードとファントムリードの違い:
アリババの内部データ 分離レベル
ダーティリード
反復不可能な読み取り
ファントムリード
読み取り未コミット
読み取りコミット済み
×
反復読み取り
×
×
シリアル化可能
×
×
×
非反復読み取りの焦点は変更です。たとえば、レコードを複数回読み取ると、一部の列の値が変更されていることがわかります。ファントム読み取りの焦点は追加することです。
または、レコードを複数回読み取り、レコードが増加または減少していることが判明した場合など、削除します。
11. トランザクション分離レベルとは何ですか? MySQL のデフォルトの分離レベルは何ですか ?
SQL 標準では、次の 4 つの分離レベルが定義されています。
READ-UNCOMMITTED ( コミットされていない読み取り ) :
最も低い分離レベル。コミットされていないデータ変更の読み取りを許可します
ダーティ読み取り、ファントム読み取り、または反復不能読み取りが発生する可能性があります
READ-COMMITTED ( 読み取りコミット ) :
同時トランザクションによってコミットされたデータを読み取ることができるため、 ダーティ リードを防ぐことができますが、
ファントム読み取りまたは反復不可能な読み取りは依然として可能です
REPEATABLE-READ ( 反復読み取り ) :
データが単独で読み取られない限り、同じフィールドを複数回読み取った結果は一貫しています。
トランザクションは自動的に変更されるため、 ダーティ リードや反復不可能な読み取りは防止できますが、ファントム リードが発生する可能性はあります
SERIALIZABLE ( シリアル化可能 ) :
ACID絶縁レベル に完全準拠した最高の絶縁レベル すべてのトランザクションを順番に
トランザクション間の干渉が完全に不可能になるように実行します。つまり、 このレベルではダーティ リードや反復不可能な読み取りを防ぐことができます。
そしてファントムリーディング
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ (可重读) 。我们可以通
SELECT @@tx_isolation ; 命令来查看
mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
这里需要注意的是:与 SQL 标准不同的地方在于 InnoDB 存储引擎在 REPEATABLE-READ (可重
读)
事务隔离级别下使用的是 Next-Key Lock 锁算法,因此可以避免幻读的产生,这与其他数据库
系统 ( SQL Server) 是不同的。所以说 InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE
READ (可重读)
已经可以完全保证事务的隔离性要求,即达到了 SQL 标准的 SERIALIZABLE( 可串
行化 ) 隔离级别。因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是
Alibaba の内部データは READ-COMMITTED ( 送信されたコンテンツを読み取ります ) されますが、知っておく必要があるのは、 InnoDB ストレージ エンジンがデフォルトで使用するということです。
REPEAaTABLE-READ (反復可能)
パフォーマンスが低下することはありません。
InnoDB ストレージ エンジンは 通常、 分散トランザクションの場合に SERIALIZABLE ( serializable )分離レベルを使用します。
12. 大きなテーブルを最適化するにはどうすればよいですか?
単一のMySQL テーブル内のレコードの数が大きすぎる 場合、データベースの CRUDパフォーマンスが大幅に低下します。一般的な最適化手段のいくつかは次のとおりです。
1. データの範囲を制限する
データ範囲を制限する条件のないクエリ文は必ず禁止してください。例: ユーザーが注文履歴をクエリしているとき、
1か月以内に制御できます。
2. 読み取り / 書き込みの分離
従来のデータベース分割スキームでは、マスター データベースが書き込みを担当し、スレーブ データベースが読み取りを担当します。
3. 縦型パーティション
データベース内のデータテーブルの関連性に応じて分割します。 たとえば、ユーザー テーブルには、ユーザーのログイン情報とユーザーの基本情報の両方が含まれます。
ユーザー テーブルを 2 つの別個のテーブルに分割したり、それらをサブデータベースとして別個のライブラリに配置したりすることもできます。
簡単に言うと、垂直分割とはデータ テーブルの列を分割し、より多くの列を含むテーブルを複数のテーブルに分割することを指します。 以下の図に示すように、
誰にとっても理解しやすくなるはずです。
1583307481617
垂直拆分的优点:
可以使得列数据变小,在查询时减少读取的 Block 数,减少 I/O 次数。此外,
垂直分区可以简化表的结构,易于维护。
垂直拆分的缺点:
主键会出现冗余,需要管理冗余列,并会引起 Join 操作,可以通过在应用层
进行 Join 来解决。此外,垂直分区会让事务变得更加复杂;
4. 水平分区
保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达
到了分布式的目的。 水平拆分可以支撑非常大的数据量。
水平拆分是指数据表行的拆分,表的行数超过 200 万行时,就会变慢,这时可以把一张的表的数据
拆成多张表来存放。举个例子:我们可以将用户信息表拆分成多个用户信息表,这样就可以避免单
一表数据量过大对性能造成影响。
1583308353521
阿里内部资料 水平拆分可以支持非常大的数据量。需要注意的一点是:分表仅仅是解决了单一表数据过大的问
题,但由于表的数据还是在同一台机器上,其实对于提升 MySQL 并发能力没有什么意义,所以 水平
拆分最好分库
水平拆分能够 支持非常大的数据量存储,应用端改造也少 ,但 分片事务难以解决 ,跨节点 Join 性能
较差,逻辑复杂。《 Java 工程师修炼之道》的作者推荐 尽量不要对数据进行分片,因为拆分会带来
逻辑、部署、运维的各种复杂度 ,一般的数据表在优化得当的情况下支撑千万以下的数据量是没有
太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络 I/O
下面补充一下数据库分片的两种常见方案:
客户端代理:
分片逻辑在应用端,封装在 jar 包中,通过修改或者封装 JDBC 层来实现。 当当网
Sharding-JDBC 、阿里的 TDDL 是两种比较常用的实现。
中间件代理:
在应用和数据中间加了一个代理层。分片逻辑统一维护在中间件服务中。 我们现
在谈的 Mycat 360 Atlas 、网易的 DDB 等等都是这种架构的实现。
详细内容可以参考: MySQL 大表优化方案 : https://segmentfault.com/a/1190000006158186
13 、分库分表之后 ,id 主键如何处理?
複数のテーブルに分割されている場合、各テーブルは 1から累積し始めるため 、これは間違っています。グローバルに一意の IDが必要です。
応援に来てください。
グローバル IDを生成するには いくつかの方法があります。
UUID : 長すぎて順序付けがなく判読できず、クエリ効率が低いため、主キーとしては適していません。ユニークなものを生み出すのに適しています
ファイル名などの名前の表示。
データベースの自己インクリメント ID : 2 つのデータベースは異なるステップ長を設定し、重複しない ID 戦略を生成して高可用性を実現します。こちらです
生成された ID は 順序付けされますが、データベース インスタンスは個別にデプロイする必要があるため、コストがかかり、パフォーマンスのボトルネックになります。
IDの生成には Redis を 使用します。パフォーマンスが向上し、柔軟で便利であり、データベースに依存しません。しかし、新しいコンポーネントの導入により、システムに問題が発生しました。
システムが複雑になり、使いやすさが低下し、コーディングが複雑になり、システムコストが増加します。
Twitter Snowflflake アルゴリズム : Github アドレス: https://github.com/twitter-archive/snowflflake
Meituan の Leaf 分散 ID 生成システム : Leaf は Meituan のオープンソースの分散 ID 生成システムであり、世界的な一意性と傾向を保証できます。
増分可能性、単調増加、情報セキュリティ、いくつかの分散スキームの比較にも言及しましたが、リレーショナル データに依存する必要もあります
ライブラリ、 Zookeeper などのミドルウェア いい感じ。Meituan 技術チームによる記事: https://tech.meituan.co
m/2017/04/21/mt-leaf.html
14. MySQLでクエリSQLを実行する方法を 教えてください。
たとえば、次の SQL ステートメントは次のとおりです。
1. リンクを取得するには MySQL で使用されるコネクタを使用します。
id= 1t_userから 名前 を選択します
Ali 内部情報 2. クエリ キャッシュ キー SQL ステートメント、 はクエリ結果で、見つかった場合は直接返されます。二次キャッシュの使用は推奨されません。
クエリ キャッシュは MySQL 8.0 で削除されました。つまり、この機能はMySQL 8.0以降には存在しません。
3. アナライザー 。字句解析と構文解析に分かれます。この段階では、 SQL の 解析と構文チェックを行うだけです。したがって、一般的な構文は間違っています
この段階では間違っています。
4. オプティマイザは、 テーブル内に複数のインデックスがある場合、またはステートメント内に複数のテーブルの関連付けがある場合に、どのインデックスを使用するかを決定します。
join ( 結合 )の際、各テーブルの接続順序を決定します。
5. エグゼキューターは 、アナライザーを通じて SQL に何をしたいのかを知らせ、オプティマイザーを通じて何をすべきかを知らせ、ステートメントの実行を開始します。所有
ステートメントを実行する際には、この権限があるかどうかも判断する必要があり、権限がない場合は、直接権限がないことを示すエラーを返します。
テーブルのエンジン定義に従ってテーブルを開き、エンジンが提供するインターフェイスを使用してテーブルの最初の行を取得し、IDがすべてであるかどうかを判断し ます
は1 に等しい 存在する場合はそのままリターンし、そうでない場合はエンジンインターフェースを呼び出し続けて次の行に進み、それが得られるまで同じ判断を繰り返す
このテーブルの最後の行に移動し、最後に戻ります。
15. インデックスの長所と短所は何ですか?
16. MySQLvarcharcharの違いは 何ですか ? varchar(30)30
それは何を表しているのでしょうか?
varchar charの違いは char は固定長型、 varchar は可変長型です。
varchar(30) 30の意味は 、最大 30 文字を格納します。 varchar (30) および (130)は、 hello oneが占有するスペース を格納します。
同じですが、後者はソート時により多くのメモリを消費します。これは、 ORDER BYcol が fifixed_length を使用して の長さを計算するためです。
( メモリ エンジンについても同様です)。
高効率の要件には charを使用し、 高スペース使用量の要件には varcharを使用します
17. int(11)11 は 何を 表しますか?
int(11) 11 は フィールドの格納範囲には影響しませんが、表示効果にのみ影響します。
18. SELECT COUNT(*) FROM table がInnoDB比較される 理由
MyISAMは 遅いですか?
Alibaba の内部データ SELECT COUNT(*) FROM tableステートメントの 場合、 WHERE条件がない場合、 InnoDB はMyISAMよりも信頼性が高くなります。
特に大きな時計の場合、かなり遅くなる可能性があります。 InnoDB はリアルタイムの統計結果、 テーブル全体のスキャン 、および MyISAMを目的としているためです。
カウンタは内部で保持され、結果は事前に保存されるため、直接返すことができます。
19. InnoDBMyISAMの違い を教えてください
MySQL 5.1 以前のバージョン では、 MyISAM が デフォルトのストレージ エンジンであり、 MySQL 5.5以降は デフォルトのストレージ エンジンです。
InnoDBストレージ エンジン がデフォルトで使用されます
MyISAM は行 レベルのロックをサポートしていません。つまり、 MyISAM は行 ではなくテーブル全体をロックします。同時に、
MyISAM は トランザクションと外部キーをサポートしていません。 MyISAM は 圧縮可能で、ストレージ容量が小さいため、 MyISAM は 大量のファイルをフィルタリングします。
データは非常に高速です。
InnoDB はトランザクション エンジンであり、トランザクションが異常にコミットされるとロールバックされます。同時に、 InnoDB は行 ロックをサポートします。また、
InnoDB は より多くのストレージ スペースを必要とするため、データとインデックスをキャッシュするためにメモリ内に専用のバッファ プールを構築します。
InnoDB は 自動クラッシュ回復機能をサポートしています。
提案: 一般に、最初に InnoDB ストレージ エンジンを選択し、 InnoDB MyISAM を混合しないようにすることをお勧めします。
一緒に使用されます。
20. MySQLインデックス タイプとは ですか?
主キーインデックス
インデックス付き列の値は一意である必要があり、NULL 値は許可されません。
通常のインデックス
MySQLの基本的なインデックス タイプ には制限がなく、インデックスを定義するカラムに重複値や null 値を挿入できます。
一意のインデックス
インデックス付き列の値は一意である必要がありますが、NULL 値も許可されます。
全文インデックス
全文インデックスは、テキスト型 CHAR、VARCHAR、および TEXT の フィールドに対してのみ作成できます。 フィールド長が比較的長い場合、一般的なフィールド長を作成すると、
インデックスを介してファジー クエリ のように実行する 場合は効率が比較的低くなりますが、この時点で全文インデックスを作成できます。 MyISAM InnoDB の両方で利用可能
全文インデックスを使用します。
空間インデックス
MySQLバージョン 5.7 以降は 空間インデックスをサポートし、OpenGIS幾何学的データ モデルをサポートします。MySQL はこれを空間的にインデックス付けします
アスペクトは、 OpenGIS 幾何学的データ モデルのルールに従います。
プレフィックスインデックス
CHAR、VARCHAR、TEXT などのテキスト型列 にインデックスを作成する場合、インデックス列の長さを指定できますが、値型は指定できません。
指定できますよ。
インデックス列数で分類)
1. 単一列インデックス
2. 複合インデックス
複合インデックスの使用は、 左端のプレフィックス マッチング原則 (左端のマッチング原則) に従う必要があります。通常、条件が許せば
場合によっては、複数の単一列インデックスの代わりに複合インデックスを使用します。

おすすめ

転載: blog.csdn.net/m0_67979925/article/details/128907643