見落とされがちな JVM 面接の質問 10 選

見落とされがちな JVM 面接の質問 10 選

[[353526]]

序文

見落とされがちな、典型的な JVM 面接の質問を 10 個まとめました。読んでいただきありがとうございます。さあみんな!

githubアドレス、星をありがとう

https://github.com/whx123/JavaHome

1. オブジェクトはヒープ内に割り当てる必要がありますか?脱出解析技術についてご存知ですか?

「オブジェクトは必ずヒープ内に割り当てられますか?」必ずしもそうではありません。 「エスケープ分析」を通じて、JVM はメソッドから脱出できないオブジェクトをスタックに割り当てます。

エスケープ分析とは何ですか?

エスケープ分析は、Java プログラムの同期負荷とメモリ ヒープ割り当ての圧力を効果的に軽減できる、関数間グローバル データ フロー分析アルゴリズムです。エスケープ分析を通じて、Java Hotspot コンパイラは新しいオブジェクト参照の使用範囲を分析し、オブジェクトをヒープ内に割り当てるかどうかを決定できます。

エスケープ解析とは、ポインタの動的範囲を解析する方法を指し、コンパイラの最適化原則のポインタ解析と形状解析に関連しています。変数 (またはオブジェクト) がメソッド内に割り当てられると、そのポインターが返されるか、グローバルに参照され、その後他のメソッドまたはスレッドによって参照されることがあります。この現象はポインタ(または参照)エスケープと呼ばれます。簡単に言えば、オブジェクトへのポインターが複数のメソッドまたはスレッドによって参照されている場合、そのオブジェクトへのポインターがエスケープしたと言えます。

脱出分析の例

  1. /**
  2. * @author カタツムリを拾う少年
  3. */
  4. パブリッククラスEscapeAnalysisTest {
  5.  
  6. 公共 静的オブジェクト オブジェクト。
  7.  
  8. //StringBuilder は他のメソッドによって変更され、メソッド外に脱出する可能性があります。
  9. パブリックStringBuilderエスケープ(文字列a、文字列b){
  10. //公式アカウント: カタツムリを拾う少年
  11. StringBuilder str = 新しい StringBuilder();
  12. str.append(a);
  13. str.append(b);
  14. strを返します
  15. }
  16.  
  17. //StringBufferを直接返さないでください。エスケープは発生しません。
  18. パブリック文字列notEscape(文字列a, 文字列b) {
  19. //公式アカウント: カタツムリを拾う少年
  20. StringBuilder str = 新しい StringBuilder();
  21. str.append(a);
  22. str.append(b);
  23. str.toString()を返します
  24. }
  25.  
  26. //外部スレッドはオブジェクトを見ることができ、エスケープが発生します
  27. パブリックvoid objectEscape(){
  28. オブジェクト = 新しいオブジェクト();
  29. }
  30.  
  31. // メソッド内でのみ表示され、エスケープは発生しません
  32. パブリックvoid objectNotEscape(){
  33. オブジェクトオブジェクト = new Object();
  34. }
  35. }

脱出分析の利点

  • スタックに割り当てると、ガベージ コレクターの実行頻度を減らすことができます。
  • 同期の排除: オブジェクトにアクセスできるのが 1 つのスレッドのみであることが判明した場合、このオブジェクトに対する操作を同期する必要はありません。
  • スカラー置換により、オブジェクトは基本型に分解され、メモリの割り当てはヒープではなくスタック上で行われるようになります。これの利点は次のとおりです。1. オブジェクト ヘッダーを生成する必要がないため、メモリ使用量が削減されます。 2. プログラムメモリの回復効率が高く、GC 頻度も削減されます。

2. 仮想マシンが Permanent Generation ではなく Metaspace を使用するのはなぜですか?

「メタスペースとは何ですか? 永久世代とは何ですか? 永久世代ではなくメタスペースを使用するのはなぜですか?」まず「メソッド領域」を確認し、次のように仮想マシン ランタイムのデータ メモリ図を見てみましょう。

メソッド領域は、ヒープと同様に、すべてのスレッドで共有されるメモリ領域です。クラス情報、定数、静的変数、ジャストインタイムでコンパイルされたコード、および仮想マシンによってロードされたその他のデータを保存するために使用されます。

「永久世代とは何ですか?それはメソッド領域とどのように関係していますか?」

HotSpot 仮想マシン上で開発および展開された場合、多くのプログラマーはメソッド領域を永続世代と呼びます。メソッド領域は仕様であり、永続世代は Hotspot によるこの仕様の実装であると言えます。 Java 7 以前のバージョンでは、メソッド領域は永続世代に実装されています。

「Metaspace とは何ですか? メソッド領域とどのように関係しますか?」

Java 8 では、HotSpots は永続的な生成をキャンセルし、Metaspace に置き換えました。つまり、メソッド領域はそのままですが、実装が永続生成からメタスペースに変わりました。

「なぜ PermGen ではなく Metaspace を使用するのですか?」

  • 永続世代のメソッド領域は、ヒープが使用する物理メモリと連続しています。

「永久世代」のサイズは、次の2つのパラメータによって設定されます。

  • -XX:PremSize: 永続世代の初期サイズを設定します
  • -XX:MaxPermSize: 永続世代の最大値を設定します。デフォルトは 64M です。

「永続世代」の場合、多くのクラスが動的に生成されると、永続世代のスペース構成が制限されるため、「java.lang.OutOfMemoryError: PermGen スペース エラー」が発生する可能性が高くなります。最も典型的なシナリオは、Web 開発に多くの JSP ページがある場合です。

  • JDK8 以降では、メソッド領域はメタスペースに存在します。物理メモリはヒープと連続しなくなり、ローカル メモリ内に直接存在します。理論的には、メタスペースのサイズはマシンのメモリのサイズによって決まります。

メタスペースのサイズは、次のパラメータを使用して設定できます。

  • -XX:MetaspaceSize、初期スペース サイズ。この値に達すると、型のアンロードのためにガベージ コレクションがトリガーされます。同時に、GC は値を調整します。大量のスペースが解放されると、値は適切に下げられます。解放されるスペースが非常に少ない場合、MaxMetaspaceSize を超えずに値が適切に増加されます。
  • -XX:MaxMetaspaceSize、最大スペース、デフォルトは無制限です。
  • -XX:MinMetaspaceFreeRatio、GC後のメタスペースの最小残容量の割合。これにより、スペースの割り当てによって発生するガベージコレクションを削減します。
  • -XX:MaxMetaspaceFreeRatio、GC後のメタスペース空き領域容量の最大パーセンテージ。スペースの解放によって発生するガベージコレクションを削減します。

「では、なぜ PermGen ではなく Metaspace を使用するのでしょうか?」

表面的には、これは OOM 例外を回避するためです。永続世代のサイズは通常、永続世代の上限を決定する PermSize と MaxPermSize を使用して設定されますが、どのくらいの大きさに設定すればよいかは必ずしもわかっていません。デフォルト値を使用すると、OOM エラーが発生しやすくなります。 Metaspace を使用する場合、ロードできるクラス メタデータの量は、MaxPermSize ではなく、システム上の実際の使用可能なスペースによって制御されるようになります。

3. Stop The Worldとは何ですか? OopMapとは何ですか?安全ポイントとは何ですか?

ガベージコレクションのプロセスにはオブジェクトの移動が含まれます。オブジェクト参照の更新の正確性を確保するには、すべてのユーザー スレッドを一時停止する必要があります。仮想マシンの設計者は、このような一時停止を「Stop The World」と表現します。

HotSpotには、「OopMap」と呼ばれるデータ構造(マッピングテーブル)があります。クラスのロードアクションが完了すると、HotSpot はオブジェクト内のどのオフセットにどのタイプのデータがあるかを計算し、それを OopMap に記録します。ジャストインタイム コンパイル プロセス中に、スタック上およびレジスタ内のどの場所が参照であるかを記録するために、OopMap も「特定の場所」に生成されます。

具体的な場所は次のとおりです。

  • 1. ループの終了(カウントされないループ)
  • 2. メソッドが戻る前/呼び出しメソッドの呼び出し命令の後
  • 3.例外が発生する可能性のある場所

これらの場所は「セーフポイント」と呼ばれます。ユーザー プログラムの実行中は、一時停止することはできず、コード命令ストリーム内の任意の場所でガベージ コレクションを開始できますが、一時停止するには安全なポイントまで実行する必要があります。

4. JVM の主なコンポーネントとその機能は何ですか?

JVMは2つのサブシステムと2つのコンポーネントで構成されています。

  • クラスローダー(クラスローディングサブシステム)
  • 実行エンジン(実行エンジンサブシステム)
  • ランタイムデータ領域
  • ネイティブ インターフェイス (ローカル インターフェイス コンポーネント)。
    • 「クラスローダー:」指定された完全修飾クラス名 (例: java.lang.Object) に従って、ランタイムデータ領域のメソッド領域にクラスファイルをロードします。
    • 「実行エンジン」:クラスの命令を実行します。
    • 「ネイティブインターフェース」:ネイティブライブラリと対話し、他のプログラミング言語が対話するためのインターフェースです。
    • 「ランタイム データ領域」: これは、よく JVM メモリと呼ばれるものです。

まず、Java ソースコードはコンパイラによってバイトコードに変換され、その後クラスローダーがバイトコードをメモリにロードしてランタイムデータ領域のメソッド領域に配置します。バイトコード ファイルは、JVM の命令セット仕様のセットに過ぎず、実行のために基盤となるオペレーティング システムに直接渡すことはできません。したがって、バイトコードを基礎となるシステム命令に変換し、それを CPU に渡して実行するために、特定のコマンド パーサー実行エンジンが必要です。このプロセスでは、プログラム全体の機能を実装するために、他の言語のネイティブライブラリインターフェース(ネイティブインターフェース)を呼び出す必要があります。

5. デーモン スレッドとは何ですか?デーモン スレッドと非デーモン スレッドの違いは何ですか?デーモンスレッドの機能は何ですか?

「デーモン スレッド」はユーザー スレッドとは異なります。 「ユーザー スレッド」は手動で作成するスレッドですが、デーモン スレッドはプログラムの実行中にバックグラウンドで提供される「一般的なサービス スレッド」です。ガベージ コレクション スレッドは、典型的なデーモン スレッドです。

「デーモン スレッドと非デーモン スレッドの違いは何ですか?」例で見てみましょう〜

  1. /**
  2. * 公式アカウントをフォロー: カタツムリを拾う少年
  3. */
  4. 公共 静的void main(String[] args)はInterruptedExceptionをスローします{
  5. スレッド t1 = 新しいスレッド(()-> {
  6. )の間{
  7. 試す {
  8. スレッドをスリープ状態にします(1000);
  9. システム。 out .println( "私は子スレッドです(ユーザースレッド。実行中です" );
  10. } キャッチ (例外 e) {
  11. }
  12. }
  13. });
  14. //デーモンスレッドとしてマーク
  15. t1.setDaemon( true );
  16. //スレッドを開始する
  17. t1.開始();
  18.  
  19. スレッドをスリープ状態にします(3000);
  20. システム。 out .println( "メインスレッドの実行が完了しました..." );
  21. }

操作結果:

デーモンスレッドとしてマークした後、「メインスレッドの破棄が停止し、デーモンスレッドも一緒に破棄される」ことがわかります。 t1.setDaemon(true) デーモン フラグを削除した場合の効果を見てみましょう。

  1. 公共 静的void main(String[] args)はInterruptedExceptionをスローします{
  2. スレッド t1 = 新しいスレッド(()->{
  3. )の間{
  4. 試す {
  5. スレッドをスリープ状態にします(1000);
  6. システム。 out .println( "私は子スレッドです(ユーザースレッド。実行中です" );
  7. } キャッチ (例外 e) {
  8. }
  9. }
  10. });
  11. //スレッドを開始する
  12. t1.開始();
  13.  
  14. スレッドをスリープ状態にします(3000);
  15. システム。 out .println( "メインスレッドの実行が完了しました..." );
  16. }

そのため、メインスレッドが終了すると、JVM も終了し、無限ループであっても、デーモンスレッドが同時にリサイクルされます。ユーザー スレッドの場合は、常に無限ループで実行されます。これがデーモン スレッドと非デーモン スレッドの違いです。

デーモンスレッドには「自身のライフサイクルを自動的に終了する」機能がありますが、非デーモンスレッドにはその機能がありません。ガベージ コレクション スレッドが非デーモン スレッドである場合、JVM を終了したいときに、ガベージ コレクション スレッドがまだ実行されているためプログラムを終了できず、非常に困った状況になります。このため、ガベージ コレクション スレッドはデーモン スレッドである必要があります。

6.WeakHashMap について聞いたことがありますか?どのように機能しますか?

「WeakHashMap」はHashMapに似ていますが、WeakHashMapのキーは「弱参照」キーです。

「弱参照」といえば、ここで4種類の参照について確認してみましょう。

  • 強い参照: Object obj = new Object()。強い参照関係が存在する限り、ガベージ コレクターは参照されたオブジェクトをリサイクルすることはありません。
  • ソフトリファレンス:原則としてリサイクルされません。メモリが不足してオーバーフローしそうな場合にのみリサイクルされます。
  • 弱参照: ガベージ コレクターが動作を開始すると、現在のメモリが十分であるかどうかに関係なく、弱参照にのみ関連付けられているオブジェクトがリサイクルされます。
  • ファントム参照: オブジェクトにファントム参照を設定する唯一の目的は、オブジェクトがリサイクルされたときにシステム通知を受信することです。

WeakHashMap が弱参照を使用するからこそ、「そのオブジェクトはいつでもリサイクルされる可能性がある」のです。 WeakHashMap クラスの動作は、ガベージ コレクターの動作に部分的に依存します。 size() メソッドへの 2 回の呼び出しが異なる値を返したり、isEmpty() への 2 回の呼び出しがそれぞれ true と false を返す可能性があります。

WeakHashMap の「動作原理」は、次の 2 つの点に答えます。

  1. WeakHashMap には弱参照の特性があり、オブジェクトはいつでもリサイクルできます。
  2. GC が発生すると、WeakHashMap はどのようにして Entry を削除しますか?

WeakHashMap 内の Entry は弱参照である WeakReference を継承しているため、「いつでもリサイクルできる」という弱参照の特性を持ちます。ソースコードを見てみましょう:

  1. プライベート静的クラス Entry<K,V> は WeakReference<Object> を拡張し、Map.Entry<K,V> を実装します {
  2. V値;
  3. 最終的なintハッシュ;
  4. エントリ<K,V>次へ;
  5.  
  6. /**
  7. * 新しいエントリを作成します。
  8. */
  9. エントリ(オブジェクトキー、V値、
  10. ReferenceQueue<Object> キュー、
  11. intハッシュ、エントリ<K,V>) {
  12. super(キー, キュー );
  13. this.value = 値;
  14. this.hash = ハッシュ;
  15. this.next =次へ;
  16. }
  17. ......

「WeakHashMap はどのようにして Entry を削除するのですか?」 GC がオブジェクトをクリーンアップするたびに、参照されたオブジェクトは ReferenceQueue に配置され、その後キューが走査されて削除されます。 WeakHashMap の追加、削除、変更、およびクエリ操作は、expungeStaleEntries() メソッドを直接的または間接的に呼び出して、期限切れのエントリを適時にクリアします。 expungeStaleEntries のソースコードを見ることができます:

  1. /**
  2. *テーブルから古いエントリ削除します
  3. */
  4. プライベートvoid expungeStaleEntries() {
  5. ( Object x; (x = queue.poll()) != null ; ) {
  6. 同期(キュー){
  7. @SuppressWarnings( "チェックなし" )
  8. エントリ<K,V> e = (エントリ<K,V>) x;
  9. int i = indexFor(e.hash,テーブル.length);
  10.  
  11. エントリ<K,V> prev =テーブル[i];
  12. エントリ<K,V> p = prev;
  13. (p != null ) の場合 {
  14. エントリ<K , V> next = p.next ;
  15. (p == e)の場合{
  16. (前 == e) の場合
  17. テーブル[i] =次へ;
  18. それ以外 
  19. // してはいけない ヌル アウトe。;
  20. // 古いエントリはHashIteratorによって使用されいる可能性があります
  21. e.value = null ; // GC のヘルプ
  22. サイズ- ;  
  23. 壊す;
  24. }
  25. 前 = p;
  26. p =次へ;
  27. }
  28. }
  29. }
  30. }

7. Java 構文シュガーについてご存知ですか? Java でよく使用される 12 個の構文シュガーは何ですか?

糖衣構文とも呼ばれる構文糖は、プログラムをより簡潔で読みやすくします。 Java で最も一般的に使用される構文糖衣には、ジェネリック、可変長パラメータ、条件付きコンパイル、自動アンパックとパック、内部クラスなど 12 種類が含まれます。

  • 構文シュガー1: スイッチは文字列と列挙型をサポートする
  • 構文シュガー 2: ジェネリック
  • 構文シュガー 3: 自動ボックス化とアンボックス化
  • 構文シュガー 4. メソッド可変長パラメータ
  • 構文シュガー 5. 列挙
  • シンタックスシュガー 6. 内部クラス
  • 構文シュガー 7. 条件付きコンパイル
  • 構文シュガー 8. アサーション
  • 構文シュガー 9: 数値リテラル
  • 構文シュガー 10. for-each
  • 構文シュガー 11. try-with-resource
  • 構文シュガー 12: ラムダ式

8. ポインターバンプとは何ですか?フリーリストとは何ですか? TLAB とは何ですか?

通常、JVM オブジェクトはヒープ メモリに配置されます (エスケープ分析が行われる場合を除く)。クラスのロード チェックに合格すると、Java 仮想マシンは新しいオブジェクトにメモリを割り当て始めます。 Java ヒープ内のメモリが完全に規則的である場合、使用済みのメモリはすべて片側に配置され、空きメモリは反対側に配置され、分割ポイントのインジケーターとしてポインタが中央に配置されます。割り当てられたメモリは、オブジェクトのサイズに等しいインスタンスによって、ポインタを空き領域に向かって移動するだけです。この割り当て方法は「ポインタ衝突」と呼ばれます。

Java ヒープ内のメモリが規則的でなく、使用済みメモリと空きメモリが絡み合っていて、ポインタの衝突が起こらない場合、仮想マシンは使用可能なメモリを記録するリストを維持し、割り当て時にリストからオブジェクト インスタンスに割り当てる大きな領域を見つけて、リスト上のレコードを更新する必要があります。この割り当て方法は「フリーリスト」と呼ばれます。

オブジェクトの作成は仮想マシンでは非常に頻繁に行われる動作であり、線形安全性の問題が発生する可能性があります。あるスレッドがオブジェクト A にメモリを割り当てており、ポインタがまだ変更されていない場合、別のスレッドがオブジェクト B にメモリを割り当てており、まだ前のポインタを参照している場合は、「問題」が発生します。

メモリ割り当てアクションは、スレッドに応じて異なるスペースに分割できます。各スレッドには、Java ヒープ内の小さなメモリ領域、つまり「TLAB (スレッド ローカル割り当てバッファー)」が事前に割り当てられます。仮想マシンは -XX:UseTLAB を介してこれを設定します。

9. CMS ガベージ コレクターの動作プロセス、CMS コレクターと G1 コレクターの違い。

CMS (Concurrent Mark Sweep) コレクター: 最短の回復一時停止時間、マークスイープ アルゴリズム、および操作プロセス (「初期マーキング、同時マーキング、再マーキング、同時スイープ」) を取得することを目的としたコレクター。コレクションの最後に大量のスペースの断片化が生成されます。写真の通りです(下の写真はインターネットから引用したものです):

「CMSコレクターとG1コレクターの違い:」

  • CMS コレクターは旧世代のコレクターであり、新世代の Serial および ParNew コレクターと一緒に使用できます。
  • G1 コレクターは古い世代と新しい世代を収集し、他のコレクターと組み合わせて使用​​する必要はありません。
  • CMS コレクターは、一時停止時間を最小限に抑えることを目的としたコレクターです。
  • G1コレクターは予測可能なガベージコレクションの一時停止時間を持っています
  • CMS コレクターは、ガベージ コレクションに「マーク アンド スイープ」アルゴリズムを使用しますが、メモリの断片化が発生しやすくなります。
  • G1 コレクターは、「マーク コンパクト」アルゴリズムを使用してスペース統合を実行し、メモリ スペースの断片化を削減します。

10. JVMのチューニング

JVM チューニングは、実際には JVM パラメータを調整すること、つまり、ガベージ コレクターとメモリ割り当てを調整して、より高いスループットとパフォーマンスを実現することです。 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 レプリケーションにおけるオブジェクトの最大有効期間しきい値を設定します。しきい値を超えるオブジェクトは古い世代に転送されます。

「ガベージコレクター関連」

  • -XX:+UseParallelGC: ガベージ コレクターを並列コレクターとして選択します。
  • -XX:ParallelGCThreads=20: 並列コレクターのスレッド数を設定します
  • -XX:+UseConcMarkSweepGC: 古い世代を同時収集に設定します。
  • -XX:CMSFullGCsBeforeCompaction=5 同時実行コレクターはメモリ空間を圧縮または整理しないため、一定期間実行すると「フラグメント」が生成され、動作効率が低下します。この値は、メモリ空間を圧縮して整理する前に GC を 5 回実行するように設定されています。
  • -XX:+UseCMSCompactAtFullCollection: 古い世代の圧縮をオンにします。パフォーマンスに影響する可能性がありますが、断片化を排除できます

「補助情報関連」

  • -XX:+PrintGCDetails は GC の詳細を出力します
  • -XX:+HeapDumpOnOutOfMemoryError は、メモリオーバーフローが発生したときに JVM がメモリスナップショットを自動的に生成することを可能にし、これを使用して問題のトラブルシューティングを行うことができます。
  • -XX:+DisableExplicitGC は、FGC を手動でトリガーすることによって発生する問題を防ぐために、システムの System.gc() を無効にします。
  • -XX:+PrintTLAB TLABスペースの使用状況を表示します

参考文献と謝辞

  • [JVM エスケープ解析] (https://segmentfault.com/a/1190000023475016)
  • [インタビュアー| JVM はなぜ永続世代を置き換えるために Metaspace を使用したのでしょうか?] (https://my.oschina.net/u/3471412/blog/4426430)
  • [メタスペース1:メタスペース全体の紹介(永久世代の置き換えの理由、メタスペースの特徴、メタスペースのメモリの表示と分析方法)](https://www.cnblogs.com/duanxz/p/3520829.html)
  • [WeakHashmap の詳細な理解] (https://blog..com/mikewang/880775)
  • [WeakHashMap の動作原理を 1 つの記事で理解する] (https://baijiahao.baidu.com/s?id=1666368292461068600&wfr=spider&for=pc)
  • [デーモンスレッドとは何か、その機能について] (https://www.cnblogs.com/quanxiaoha/p/10731361.html)
  • [Java での TLAB の簡単な分析] (https://www.jianshu.com/p/8be816cbb5ed)
  • 《Java仮想マシンの深い理解》

この記事はWeChatの公開アカウント「カタツムリを拾う少年」から転載したものです。下のQRコードからフォローできます。この記事を転載する場合は、カタツムリを採る少年の公式アカウントまでご連絡ください。

<<:  エッジコンピューティング: 流行語か未来か?

>>:  Linux 仮想化 KVM-Qemu 割り込み仮想化の分析

推薦する

#BlackFive# edgenat: BlackFive + 2周年記念、全VPSが30%オフ、韓国CN2/米国AS4837/米国CN2 GIA

edgenatは2周年を迎え、ブラックフライデーの時期でもあるため、特別なイベントを開催します。すべ...

Baidu スパイダーをあなたのウェブサイトのようにする方法

最適化を行っている多くの友人が、Baidu のインデックス作成が遅くなった、または Baidu の評...

システム「Thanos」 - Java 仮想マシン

[[328776]]コンセプト仮想マシン: 完全なハードウェア システム機能をシミュレートし、完全に...

YYの秘密のエンターテイメントの世界:女性音楽教師がオンライン歌手に転身

レレはYYで最初に歌った人の一人です記者 ブ・シャン 写真 王欣レレ氏はオフィスに戻り、中国工商銀行...

budgetvm-Alipay/$9.99/Xen/2g メモリ/100g ハードディスク/4T トラフィック/2IP/4 コンピュータ ルーム

何百GBもの美しい写真が集まっているので、それをバックアップしてみんなと共有できる良い場所を見つけた...

分散システムの噂

[[259783]] Redis、Cassandra、Amazon S3、BitTorrent など...

目を引く EDM 電子メール テンプレートをデザインするにはどうすればよいでしょうか?

月収10万元の起業の夢を実現するミニプログラム起業支援プラン誰もが気に入る、あるいは賞賛するような大...

誘導から強制まで、Googleは私たちに「教え」てきた

私は数年前から Google のことを知っていますが、詳しくは知りません。しかし、SEO の観点から...

Baidu Statistics、訪問時間をアップグレード

百度の外部リンクツールのリリースに伴い、百度統計もそれに追随し、昨夜7時30分頃にアップグレードしま...

オンサイト最適化がオフサイト最適化を上回り、ウェブサイトのランキングをさらに向上させる方法

SEO が 2 つのカテゴリに分かれていることは誰もが知っています。これら 2 つのカテゴリは異なる...

ランキングに影響を与える5つの最大のアルゴリズム

Baiduのアルゴリズムは実はあまり奥が深くなく、各アルゴリズムを担当するエンジニアも異なるため、そ...

FIT2CLOUDがシリーズCおよびC+の資金調達を完了し、中国のマルチクラウド管理市場をリードし続けます

2020年4月16日、中国のマルチクラウド管理プラットフォームソフトウェアおよびサービスプロバイダー...

FireNet インターコネクト エディター: 高負荷スペースに関する簡単な説明

ご存知のとおり、99% の仮想ホストは大量のトラフィックに耐えられません。多くのお客様が一定期間弊社...

STO と JD.com が「決裂」: スペアパーツ倉庫物流入札で JD.com を非難

1社は民間の宅配便大手、もう1社は物議を醸す電子商取引界の大物だ。外の世界では「不可分」とみなされて...

大手のモバイル インターネット ゲーム: 囲い込み、プラットフォーム、そして未知のもの

(文:季勇青、袁銀、編集者:王奇) Android アプリ ストアで「QQ」を検索すると、モバイル ...