ホームページ  >  記事  >  ウェブフロントエンド  >  中級および上級の Android 面接の質問 (回答付き)

中級および上級の Android 面接の質問 (回答付き)

藏色散人
藏色散人転載
2020-07-31 13:59:065437ブラウズ

おすすめ: 「2020 Android 面接質問まとめ [コレクション]

##1,java==equalsハッシュコード違い

基本データ型の==比較値は等しい

クラスの==比較のメモリアドレス、つまり, 同じオブジェクトかどうかは、equals をオーバーライドせずに、メモリアドレスを比較し、元の実装も == など String などで、equals メソッドをオーバーライドします,
hashCode も Object クラスのメソッドです。離散整数を返します。クエリ速度を向上させるためにコレクション操作で使用されます。 (HashMap、HashSet などは、それらが同じかどうかを比較します)

2 つのオブジェクトが等しい場合、Java 実行環境は、それらのハッシュコードが等しいはずだと考えます。

2 つのオブジェクトが等しくない場合、それらのハッシュコードは等しい可能性があります。

2 つのオブジェクトのハッシュコードが等しい場合、それらは必ずしも等しいとは限りません。

2 つのオブジェクトのハッシュコードが等しくない場合、それらは等しくなくてはなりません。

2intinteger の違い

int 基本型

オブジェクトの整数カプセル化クラス int

3String StringBufferStringBuilder違い

文字列:文字列定数は、値を頻繁に変更する必要がある状況には適していません。変更するたびに、新しいオブジェクトを生成するのと同じです。

StringBuffer: 文字列変数 (スレッド セーフ)
StringBuilder: 文字列変数 (スレッド セーフ) -threaded 操作が可能です。StringBuffer

4 よりもわずかに効率的です。内部クラスとは何ですか?内部クラスの役割

内部クラスは外部クラスのプロパティに直接アクセスできます

Java の内部クラスは主に
メンバー内部クラスに分かれています,ローカル内部クラス (メソッドとスコープ内でネストされている)、匿名内部クラス (コンストラクター メソッドなし)、静的内部クラス (静的に変更されたクラス。周辺クラスの非静的メンバー変数とメソッドは周辺クラスに依存しません)

5、プロセスとスレッドの違い

プロセスは CPU リソース割り当ての最小単位であり、スレッドは CPU スケジューリングの最小単位です。

リソースはプロセス間で共有できませんが、スレッドは、スレッドが配置されているプロセスのアドレス空間とその他のリソースを共有します。
プロセスには複数のスレッドを含めることができ、プロセスはプロセスまたはスレッドを開始できます。
スレッドは 1 つのプロセスにのみ所属できます。スレッドは同じプロセスのリソースを直接使用できます。スレッドはプロセスの存在に依存します。

6finalfinallyfinalize違い

final: クラス、メンバー変数、およびメンバーメソッドを変更します。クラスは継承できず、メンバー変数は不変で、メンバーメソッドは変更できません。オーバーライドできません
finally: try...catch... と一緒に使用して、例外が発生するかどうかに関係なく確実に呼び出せるようにします。
finalize: クラスのメソッド。このメソッドはガベージの前に呼び出されます。サブクラスは、リソースのリサイクルを実現するために、finalize() メソッドをオーバーライドできます

7シリアル化可能な および Parcelable 違い

シリアル化可能な Java シリアル化インターフェイスは、ハードディスク上での読み取りおよび書き込みプロセス中に多数の一時変数を生成し、内部では大量の I/O 操作が行われるため、非常に非効率的です。
Parcelable Android シリアル化インターフェイスは効率的ですが、メモリ内での読み取りと書き込みが面倒です (AS にはワンクリックで必要なメソッドを生成する関連プラグインがあります)。オブジェクトはディスクに保存できません

8 静的プロパティと静的メソッドは継承できますか?書き換えることはできますか?なぜ?

継承可能、オーバーライド不可、ただし非表示
静的メソッドと静的プロパティがサブクラスで定義されている場合、この時点では親クラスの静的メソッドまたは静的プロパティは「非表示」と呼ばれます。親クラスの静的メソッドとプロパティを呼び出したい場合は、親クラス名、メソッド、または変数名を使用して直接呼び出します。

9、メンバー内部クラス、静的内部クラス、ローカル内部クラス、匿名内部クラス、およびプロジェクトでのアプリケーションの理解

ava Internalクラスは主に メンバー内部クラス ローカル内部クラス (メソッドとスコープ内でネストされている)、匿名内部クラス (コンストラクター メソッドなし)、 に分かれています。静的内部クラス (静的に変更されたクラスは、外部クラスの非静的メンバー変数やメソッドを使用できず、外部クラスに依存しません)

内部クラスを使用する最も魅力的な理由は次のとおりです。内部クラスは独立して (インターフェースの) 実装を継承できるため、外部クラスが (インターフェースの) 実装を継承したかどうかは、内部クラスには影響しません。
Java は多重継承をサポートしていないため、複数のインターフェイスの実装をサポートしています。ただし、インターフェイスを使用して解決するのが難しい問題が発生する場合があります。このとき、内部クラスによって提供される機能を使用して、複数の具体クラスまたは抽象クラスを継承することで、これらのプログラミングの問題を解決できます。インターフェイスは問題の一部を解決するだけであり、内部クラスは多重継承の解決策をより完全にするものであると言えます。

10文字列 整数 に変換する方法

##String →integer Intrger.parseInt(string);

Integer→string Integer.toString();

11、どのような状況でオブジェクトはガベージ コレクション メカニズムによって破棄されますか?

1. すべてのインスタンスにはアクティブなスレッド アクセスがありません。

2. 他のインスタンスからアクセスされない循環参照インスタンス。

3.Java にはさまざまな参照型があります。インスタンスがガベージ コレクションの対象となるかどうかは、その参照タイプによって異なります。

どのような種類のオブジェクトが無駄なオブジェクトであるかを判断するため。ここには 2 つの方法があります:

1. マーク カウント メソッドを使用します:

メモリ内のオブジェクトをマークします。オブジェクトが 1 回参照されると、カウントが 1 増加し、参照カウントが 1 つ減り、カウントが 0 に達すると、オブジェクトはリサイクル可能になります。もちろん、これには問題も発生します。循環参照を持つオブジェクトを識別してリサイクルすることができません。したがって、2 番目の方法があります:

2. ルート検索アルゴリズムを使用します:

ルートから開始して、到達可能なすべてのオブジェクトを検索するため、残りのオブジェクトはリサイクルする必要があります

12、静的プロキシと動的プロキシの違いは、どのようなシナリオで使用されますか?

静的プロキシ クラス: プログラマによって作成されるか、特定のツールによって自動的に生成され、コンパイルされます。プログラムが実行される前に、プロキシ クラスの .class ファイルはすでに存在します。動的プロキシ クラス: プログラムの実行時にリフレクション メカニズムを使用して動的に作成されます。

14Java でポリモーフィズムを実装するメカニズムは何ですか?

回答: メソッドのオーバーライドとオーバーロードは、Java ポリモーフィズムの異なる表現です。

オーバーライドは、親クラスとサブクラス間のポリモーフィズムの一形態です。クラスにおけるポリモーフィズムの現れで​​す。

16

、あなたの意見をお聞かせください Javaリフレクションの理解

JAVA リフレクション メカニズムは実行状態にあります。どのクラスについても、このクラスのすべてのプロパティとメソッドを知ることができます。また、どのオブジェクトについても、そのクラスのメソッドおよびプロパティを呼び出すことができます。オブジェクトから始まり、リフレクション(クラスクラス)を通じて、クラスの完全な情報(クラス名、クラスタイプ、パッケージ、そのクラスが持つすべてのメソッド Method[] タイプ、メソッドの完全な情報(修飾子、戻り値を含む))を取得できます。タイプ、例外、パラメーターのタイプ)、すべての属性 Field[]、特定の属性の完全な情報、コンストラクター (Constructors)、クラス自体の属性またはメソッドの呼び出し 概要: クラス、オブジェクト、およびメソッドのすべての情報を取得します。実行中のプロセス。

17Java アノテーション

# # についての理解を話してください。 #メタアノテーション

メタアノテーションの役割は、他のアノテーションに注釈を付けることです。 Java 5.0 では、他のアノテーション タイプの説明を提供するために使用される 4 つの標準メタアノテーション タイプが定義されました。

1.@Target

2.@Retention

3.@Documented

4.@Inherited

18 #Java ## の String について理解する #Java

ソース コードでは、文字列は、変更または継承できない定数である Final で変更されます。 19

String

なぜ不変になるように設計する必要があるのでしょうか?

1. 文字列プールの要件

文字列プールは、メソッド領域内の特別な記憶領域です。文字列が作成され、その文字列がプール内にある場合、文字列を再作成して変数への参照を返すのではなく、文字列への参照がただちに変数に返されます。文字列が不変でない場合、ある参照 (string2 など) で文字列を変更すると、別の参照 (string1 など) でダーティなデータが発生します。

2. 文字列キャッシュのハッシュ コードを許可する

文字列のハッシュ コードは、HashMap などの Java でよく使用されます。 String の不変性により、ハッシュ コードが常に同じになるため、変更について心配する必要がありません。このアプローチは、ハッシュ コードを使用するたびに再計算する必要がなく、はるかに効率的であることを意味します。

3. セキュリティ文字列は、ネットワーク接続 (ネットワーク接続)、ファイルを開く (ファイルを開く) など、Java クラスのパラメーターに広く使用されます。 String が不変でない場合、ネットワーク接続とファイルが変更され、一連のセキュリティ上の脅威につながります。その操作方法は機械に接続されていると思われていましたが、実際にはそうではありませんでした。リフレクションのパラメータはすべて文字列であるため、一連のセキュリティ上の問題も発生します。 20オブジェクト等しいおよび

hashCode

メソッドの書き換え、なぜですか?

まず、equals とハッシュコードの関係は次のとおりです:

1. 2 つのオブジェクトが同じである場合 (つまり、equals を使用して比較し、true を返す場合)、 ;

2. 2 つのオブジェクトの hashCode が同じである場合、それらは必ずしも同じであるとは限りません (つまり、equals で比較すると false が返されます) ハッシュコード方式はプログラムの効率化を目的として実装されているため、先に進めてください ハッシュコードの比較が異なる場合は等値比較を行う必要がなくなり、等値比較の回数が大幅に削減されます。比較すると、効率の向上は明らかです 21List、Set、Map の違い

Set は最も単純な 1 種類のコレクションです。コレクション内のオブジェクトは特定の順序で並べられておらず、重複するオブジェクトはありません。 Set インターフェイスは主に 2 つの実装クラスを実装します: HashSet: HashSet クラスはハッシュ アルゴリズムに従ってセット内のオブジェクトにアクセスし、アクセス速度は比較的高速です

TreeSet: TreeSet クラスは SortedSet インターフェイスを実装し、セット内のオブジェクトにアクセスします。オブジェクトはソートされます。

List の特徴は、要素が線形に格納され、繰り返しオブジェクトをコレクションに格納できることです。

ArrayList(): 長さを変更できる配列を表します。要素にはランダムにアクセスでき、ArrayList() への要素の挿入と削除は時間がかかります。

LinkedList(): 実装ではリンク リスト データ構造を使用します。挿入と削除は高速ですが、アクセスは低速です。

Map は、キー オブジェクトと値オブジェクトをマップするコレクションであり、その各要素には、キー オブジェクトと値オブジェクトのペアが含まれます。 Map は Collection インターフェイスから継承しません。Map コレクションから要素を取得する場合、キー オブジェクトが指定されている限り、対応する値オブジェクトが返されます。 ######HashMap: ハッシュ テーブルのマップ ベースの実装。キーと値のペアの挿入とクエリのコストは固定です。容量と負荷率はコンストラクターを通じて設定して、コンテナーのパフォーマンスを調整できます。 ######LinkedHashMap: HashMap に似ていますが、反復処理の際、「キーと値のペア」が取得される順序は、挿入順序、つまり最も最近使用されていない (LRU) 順序になります。 HashMap よりもわずかに遅いだけです。内部順序を維持するためにリンク リストを使用するため、反復アクセスが高速になります。 ###

TreeMap: 赤黒ツリー データ構造に基づいた実装。 「キー」または「キーと値のペア」を表示すると、それらは並べ替えられます (順序は Comparabel または Comparator によって決まります)。 TreeMap の特徴は、得られる結果がソートされていることです。 TreeMap は、サブツリーを返すことができる subMap() メソッドを持つ唯一の Map です。

WeakHashMao: 弱いキー (弱いキー) マップ、マップで使用されるオブジェクトも解放できます: これは、特殊な問題を解決するために設計されています。マップの外に「キー」を指す参照がない場合、この「キー」はガベージ コレクターによってリサイクルできます。

26ArrayMapHashMap# の比較

##1. さまざまな保存方法

HashMap 内に HashMapEntryb56561a2c0bc639cf0044c0859afb88f[] オブジェクトがあり、各キーと値のペアがこのオブジェクトに保存されます。 put メソッドでキーと値のペアを追加すると、新しい HashMapEntry オブジェクトが作成されます。

2. データを追加する場合、展開するときの処理が異なります。新しい操作が実行され、オブジェクトが再作成されます。 、非常に高価です。 ArrayMap はコピーデータを使用するため、比較的効率が高くなります。

3. ArrayMap は配列縮小の機能を提供します。クリアまたは削除後、スペースがあるかどうかに関係なく、配列は再び縮小されます。

4. ArrayMap は二分探索を使用します。

29HashMapHashTable の違い

1 HashMap はスレッドセーフではありません。より効率的ですが、メソッドは Synchronize ではありません。外部同期を提供する必要があります。containsvalue メソッドと containsKey メソッドがあります。

Hashtable はスレッドセーフであり、null キーと値を許可しません。効率がわずかに低く、メソッドは同期です。 contains メソッドがあります。 Hashtable は Dictionary クラス

30HashMap および HashSet の違いを継承します。

hashMap: HashMap は Map インターフェイスを実装します。HashMap はキーと値のペアを保存します。要素をマップに配置するには put() メソッドを使用します。HashMap はキー オブジェクトを使用してハッシュコードを計算します.Value、HashMap はオブジェクトの取得に一意のキーが使用されるため高速です。

HashSet は Set インターフェイスを実装します。HashSet はオブジェクトのみを保存します。セットに要素を入れるには add() メソッドを使用します。HashSet はメンバー オブジェクトを使用してハッシュコード値を計算します。ハッシュコードは 2 つのオブジェクトで同じである可能性があるため、等しい () メソッドは、オブジェクトが等しいかどうかを判断するために使用されます。2 つのオブジェクトが異なる場合は、false を返します。 HashSet は HashMap よりも低速です。

31HashSet、および HashMap要素が設定されているかどうかを確認する方法重複していますか?

HashSet は重複した要素を追加できません。add (Object) メソッドが呼び出されるとき、

はまず Object の hashCode メソッドを呼び出して、hashCode がすでに存在するかどうかを確認します。存在する場合は、存在しない場合は、直接挿入されます。要素。すでに存在する場合は、Object オブジェクトの等しいメソッドを呼び出して、true を返すかどうかを確認します。true の場合は、要素がすでに存在することを意味します。false の場合は、要素が挿入されます。

33ArrayListLinkedList の違いもアプリケーション シナリオとして

ArrayList は配列に基づいて実装されており、ArrayList はスレッド セーフではありません。

LinkedList は二重リンク リストに基づいて実装されます:

使用シナリオ:

(1) アプリケーションが各要素に対して大量のアクセスまたは削除操作を実行する場合インデックス位置、ArrayList オブジェクトは LinkedList オブジェクトよりもはるかに優れています;

(2) アプリケーションが主にリストをループし、ループ中に挿入または削除する場合、LinkedList オブジェクトは ArrayList オブジェクトよりもはるかに優れています;

34、配列とリンク リストの違い

配列: 要素をメモリに連続的に保存します。利点: データが連続的に保存されるため、メモリアドレスは連続しているため、データを検索するときに効率的ですが、欠点は、保存する前に連続したメモリ空間を申請する必要があり、その空間のサイズはコンパイル中に決定する必要があることです。運用中に必要に応じて領域のサイズを変更することはできません データが比較的大きい場合は範囲​​外になる可能性があります データが比較的小さい場合は無駄になる可能性があります メモリ領域。データ数を変更する場合、データの追加、挿入、削除の効率が低下します。

リンク リスト: メモリ空間の動的アプリケーションです。配列のように事前にメモリ サイズを申請する必要はありません。リンク リストは、使用するときにのみ適用する必要があります。メモリ空間は、必要に応じて動的に適用または削除できるため、データの増加や削除、挿入は配列よりも柔軟です。また、リンク リスト内のデータはメモリ内の任意の場所に存在することができ、アプリケーションを通じて (つまり、既存の要素のポインタを通じて) データを関連付けることができるという事実もあります。

35、スレッドを開いてください 3 つの方法がありますか?

ava にはスレッドを作成する 3 つの方法があります。つまり、Thread クラスの継承、Runable インターフェイスの実装、およびスレッド プールの使用です。

36、スレッドとプロセスの違いは何ですか?

スレッドはプロセスのサブセットです。プロセスには多数のスレッドを含めることができ、各スレッドは異なるタスクを並行して実行します。異なるプロセスは異なるメモリ空間を使用し、すべてのスレッドは同じメモリ空間を共有します。これをスタック メモリと混同しないでください。各スレッドには、ローカル データを保存するための独自のスタック メモリがあります。

38run()start()## の違い

#この質問はよく聞かれますが、それでも面接官の Java スレッド モデルの理解を区別する可能性があります。 start() メソッドは、新しく作成されたスレッドを開始するために使用され、start() は内部で run() メソッドを呼び出します。これには、run() メソッドを直接呼び出す場合とは異なる効果があります。 run() メソッドを呼び出すと、元のスレッドでのみ呼び出されます。新しいスレッドが開始されていない場合は、start() メソッドによって新しいスレッドが開始されます。

39. 特定のメソッドに許可される同時アクセス スレッドの数を制御するにはどうすればよいですか?

semaphore.acquire()はセマフォを要求しますが、このときのセマフォの数は-1です(使用可能なセマフォがなくなったら、つまりセマフォの数がマイナスになったら再度要求してください)他のスレッドがセマフォを解放するまでブロックされます)

semaphore.release() はセマフォを解放します。この時点でのセマフォの数は 1

40 Java; wait メソッドと seelp メソッドの違い

Java プログラムの待機とスリープは両方とも何らかの形式の一時停止を引き起こし、さまざまなニーズを満たすことができます。 wait() メソッドはスレッド間通信に使用されます。待機条件が true で他のスレッドが起動されている場合はロックが解放されますが、sleep() メソッドは CPU リソースを解放するか、現在のスレッドを一定期間停止するだけです。時間はかかりますが、ロックは解除されません。

41wait/notify キーワード についての理解について話します。

オブジェクトの同期ロックを待っています。このメソッドを呼び出す前に、オブジェクトの同期ロックを取得する必要があります。そうでない場合、コンパイルは成功しますが、実行時に例外 IllegalMonitorStateException が発生します。

任意のオブジェクトの wait() メソッドを呼び出すと、スレッドがブロックされ、スレッドは実行を続行できなくなり、オブジェクトのロックが解放されます。

オブジェクトの同期ロックを待機しているスレッドをウェイクアップします (複数の待機がある場合は 1 つだけウェイクアップします)。このメソッドを呼び出す場合、待機状態のスレッドを正確にウェイクアップすることはできないことに注意してください。代わりに、JVM は優先順位ではなく、どのスレッドをウェイクアップするかを決定します。

任意のオブジェクトのnotify()メソッドを呼び出すと、オブジェクトのwait()メソッドを呼び出すことによってブロックされていたランダムに選択されたスレッドがブロック解除されます(ただし、ロックが取得されるまで実行されません)。

42. スレッドのブロックの原因は何ですか?スレッドを閉じるにはどうすればよいですか?

ブロッキング メソッドは、プログラムが何もせずにメソッドの完了を待つことを意味します。ServerSocket の accept() メソッドは、クライアントの接続を待ちます。ここでのブロックとは、呼び出し結果が返される前に、現在のスレッドが一時停止され、結果が取得されるまで戻らないことを意味します。さらに、タスクが完了する前に戻る非同期メソッドや非ブロッキング メソッドもあります。

1 つは、内部で stop() メソッドを呼び出すことです。

もう 1 つは、スレッドを停止するマークを自分で設定することです (推奨)

43 、スレッドの安全性を確保するにはどうすればよいですか?

1.synchronized;

2.wait,notify in the Objectメソッド;

3.ThreadLocalメカニズムを実現します。

44、スレッド同期を実現するにはどうすればよいですか?

1. 同期キーワードの変更方法。 2. synchronized キーワードで変更されたステートメント ブロック 3. 特殊なドメイン変数 (揮発性) を使用してスレッド同期を実現します

45、スレッド間操作リスト

List list = Collections.synchronizedList(new ArrayList());

46Synchronized# について話しましょう##キーワード、クラス ロック、メソッド ロック、および再入可能ロックについての理解 Java オブジェクト ロックとクラス ロック: Java オブジェクト ロックとクラス ロックはロック内にあります。概念は基本的に組み込みロックと同じですが、2 つのロックは実際には大きく異なります。オブジェクト ロックはオブジェクト インスタンス メソッドまたはオブジェクト インスタンスに使用され、クラス ロックはクラスの静的メソッドに使用されます。クラスのクラスオブジェクト。クラスには多数のオブジェクト インスタンスが存在する可能性があることがわかっていますが、各クラスにはクラス オブジェクトが 1 つしかないため、異なるオブジェクト インスタンスのオブジェクト ロックは互いに干渉しませんが、各クラスに存在するクラス ロックは 1 つだけです。ただし、注意しなければならない点が 1 つあります。実際、クラス ロックは概念的なものにすぎず、実際には存在しません。ロック インスタンス メソッドと静的メソッドの違いを理解するためにのみ使用されます。

49同期 揮発性 キーワード ## の違い

#1. volatile の本質は、レジスタ (作業メモリ) 内の現在の変数の値が不確実であり、メイン メモリから読み取る必要があることを jvm に伝えることです。同期ロックは、現在の変数と現在のスレッドのみがこの変数にアクセスでき、他のスレッドはブロックされます。

2. Volatile は変数レベルでのみ使用できます; synchronized は変数、メソッド、およびクラス レベルで使用できます。

3. Volatile は変数の変更とクラスの可視性のみを実現できます。原子性は保証できません。同期では変数変更の可視性と原子性が保証されますが、

4.volatile ではスレッド ブロックが発生しませんが、同期ではスレッド ブロックが発生する可能性があります。

5. volatile とマークされた変数はコンパイラによって最適化されません; synchronized とマークされた変数はコンパイラによって最適化できます

51ReentrantLock synchronized、および volatileComparison

Ava は、これまで長い間、同期されたキーワードを通じてのみ相互排他を実現できましたが、これにはいくつかの欠点がありました。たとえば、ロックの外側にメソッドやブロック境界を拡張したり、ロックを取得しようとしたときに途中でキャンセルしたりすることはできません。 Java 5 では、これらの問題を解決するために、Lock インターフェースを介したより複雑な制御が提供されます。 ReentrantLock クラスは Lock を実装します。Lock は同期と同じ同時実行性とメモリ セマンティクスを持ち、拡張可能です。

53、デッドロックの必要条件は4つ?

デッドロックの原因

1. システム リソースの競合

システム リソースの競合により、システム リソースの不足やリソースの不適切な割り当てが発生し、デッドロックが発生します。

2. プロセスの実行と進行の順序が不適切です

相互排他条件: リソースは一度に 1 つのプロセスのみが使用できます。つまり、特定のリソースのみが占有できます。一定期間内の 1 つのプロセスによって。このとき、他のプロセスがリソースを要求した場合、要求元のプロセスは待つことしかできません。

要求と保持の条件: プロセスは少なくとも 1 つのリソースを維持していますが、新しいリソース要求を行っており、そのリソースは他のプロセスによって占有されています。この時点で、要求元のプロセスはブロックされていますが、はリソースを取得していません。リソースはそのまま残ります。

非剥奪条件: プロセスによって取得されたリソースは、完全に使用される前に他のプロセスによって強制的に奪われることはできません。つまり、リソースを取得したプロセスによってのみ解放できます (解放できるのはリソースだけです)積極的に)。

ループ待ち条件: 複数のプロセス間でリソースを待つエンドツーエンドのループ関係が形成される

この 4 つの条件がデッドロックの必須条件となります。システムでは、これらの条件が満たされている必要があり、上記の条件のいずれかが満たされない限り、デッドロックは発生しません。

デッドロックの回避と防止:

デッドロック回避の基本的な考え方:

システムは、満たせるシステムごとにプロセスによって発行されたリソース要求を動的にチェックします。チェックの結果、リソースを割り当てるかどうかが決定され、割り当て後にシステムがデッドロックする可能性がある場合は割り当てられず、そうでない場合は割り当てられます。これは、システムがデッドロック状態にならないようにするための動的な戦略です。

デッドロックの理由、特にデッドロックに必要な 4 つの条件を理解すると、デッドロックを可能な限り回避、防止、排除することができます。したがって、システム設計とプロセスのスケジューリングの観点からは、これら 4 つの必要な条件が当てはまらないことを確認する方法と、プロセスがシステム リソースを永続的に占有することを回避するための合理的なリソース割り当てアルゴリズムを決定する方法に注意してください。また、プロセスが待機状態にあるときにリソースを占有しないようにすることも必要です。したがって、リソースの割り当ては適切に計画する必要があります。

デッドロック回避とデッドロック防止の違い:

デッドロック防止とは、デッドロックに必要な 4 つの条件のうち少なくとも 1 つを破壊し、デッドロックの発生を厳密に防止し、ロックを回避することです。デッドロックの必要条件が存在しても、必ずしもデッドロックが発生するとは限らないため、デッドロックの必要条件の存在を厳密に制限するものではありません。デッドロック回避とは、システム運用中に最終的にデッドロックが発生しないように注意を払うことです。

56、スレッド プールとは何か、その使用方法?

スレッドの作成には高価なリソースと時間がかかりますタスクが来てからスレッドを作成すると、応答時間が長くなり、プロセスで作成できるスレッドの数が制限されます。このような問題を回避するために、プログラム起動時に処理に応答するスレッドを複数用意し、これをスレッドプールと呼び、その中のスレッドをワーカースレッドと呼びます。 JDK1.5 以降、Java API はさまざまなスレッド プールを作成できるように Executor フレームワークを提供します。たとえば、単一のスレッド プールは一度に 1 つのタスクを処理します。固定数のスレッド プールまたはキャッシュ スレッド プール (有効期間の短いタスクが多いプログラムに適した拡張可能なスレッド プール)。

57Java におけるヒープとスタックの違いは何ですか??

この質問がマルチスレッドおよび同時実行の面接質問として分類されているのはなぜですか?スタックはスレッドと密接に関係するメモリ領域であるためです。各スレッドには、ローカル変数、メソッド パラメータ、スタック呼び出しを保存するための独自のスタック メモリがあり、あるスレッドに保存された変数は他のスレッドには表示されません。ヒープは、すべてのスレッドによって共有される共通メモリ領域です。オブジェクトはヒープ内に作成されます。効率を向上させるために、スレッドはオブジェクトをヒープから独自のスタックにキャッシュします。複数のスレッドがこの変数を使用すると、問題が発生する可能性があります。このとき、揮発性変数が影響する可能性があります。スレッドがメイン スタックから開始する必要があるため、メモリから変数の値を読み取ります。

58、3 つのスレッド T1T2、# があります##T3、それらが順番に実行されることを確認するにはどうすればよいですか?

マルチスレッドでは、スレッドを特定の順序で実行する方法がたくさんあります。スレッド クラスの join() メソッドを使用して、一方のスレッドで別のスレッドを開始し、もう一方のスレッドで別のスレッドを開始することができます。スレッドはスレッドを完了して続行します。 3 つのスレッドの順序を確保するには、T1 が最初に終了し、T3 が最後に終了するように、最後のスレッドを最初に開始する必要があります (T3 が T2 を呼び出し、T2 が T1 を呼び出します)。

スレッド間通信

スレッドが CPU スケジューリングの最小単位であることはわかっています。 Android では、メインスレッドは時間のかかる操作を実行できず、サブスレッドは UI を更新できません。スレッド間の通信にはブロードキャスト、Eventbus、インターフェイスのコールバックなどさまざまな方法がありますが、Android では主にハンドラーが使用されます。ハンドラーは、sendmessage メソッドを呼び出して、メッセージを含むメッセージを Messagequeue に送信します。ルーパー オブジェクトは、loop メソッドを継続的に呼び出してメッセージをメッセージキューから取り出し、処理のためにハンドラーに渡します。これにより、スレッド間通信が完了します。 。

スレッド プール

Android には、FixedThreadPool、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor の 4 つの一般的なスレッド プールがあります。

FixedThreadPool スレッド プールは、Executor の新しいFixedThreadPool メソッドを通じて作成されます。スレッドプール内のスレッド数が固定であるのが特徴です。スレッドがアイドル状態であっても、スレッド プールが閉じられない限り、スレッドはリサイクルされません。すべてのスレッドがアクティブになると、新しいタスクはキュー内でスレッドの処理を待機します。 FixedThreadPool にはコア スレッドのみがあり、非コア スレッドはないことに注意してください。

CachedThreadPool スレッド プールは、Executor の newCachedThreadPool を通じて作成されます。これは、可変数のスレッドを持つスレッド プールです。コア スレッドはなく、非コア スレッドのみがあります。スレッド プール内のすべてのスレッドがアクティブになると、新しいタスクを処理するために新しいスレッドが作成されます。それ以外の場合は、アイドル状態のスレッドが新しいタスクの処理に使用されます。スレッド プール内のスレッドにはタイムアウト メカニズムがあり、タイムアウト メカニズムは 60 秒です。この時間が経過すると、アイドル状態のスレッドがリサイクルされます。このタイプのスレッド プールは、時間のかからない大量のタスクを処理するのに適しています。ここで、CachedThreadPool のタスク キューは基本的に空であることに注意してください。

ScheduledThreadPool スレッド プールは、Executor の newScheduledThreadPool を通じて作成されます。そのコア スレッドは固定されていますが、非コア スレッドの数は固定されておらず、非コア スレッドがアイドル状態になると、すぐにリサイクルされます。 。この種類のスレッドは、スケジュールされたタスクや一定期間で繰り返し実行されるタスクの実行に適しています。

SingleThreadExecutor スレッド プールは、Executor の newSingleThreadExecutor メソッドによって作成されます。このタイプのスレッド プールにはコア スレッドが 1 つだけあり、非コア スレッドはありません。これにより、すべてのタスクを確実に実行できます。同じスレッドで順番に実行されるため、スレッドの同期の問題を考慮する必要はありません。

AsyncTask動作原理

AsyncTask は、Android 自体が提供する軽量の非同期タスク クラスです。スレッド プールでバックグラウンド タスクを実行し、実行の進行状況と最終結果をメイン スレッドに渡して UI を更新できます。実際、AsyncTask はスレッドとハンドラーを内部でカプセル化します。 AsyncTask は、バックグラウンド タスクの実行やメイン スレッドでの UI の更新には非常に便利ですが、特に時間のかかるバックグラウンド操作には適していません。特に時間のかかるタスクには、個人的にはスレッド プールを使用することをお勧めします。

AsyncTask は 4 つのコア メソッドを提供します:

1. onPreExecute(): このメソッドはメイン スレッドで実行され、非同期タスクを実行する前に呼び出されます。通常、いくつかの準備作業に使用されます。 。

2. doInBackground(String... params): このメソッドはスレッド プールで実行され、非同期タスクを実行するために使用されます。このメソッドでは、タスクの進行状況は、publishProgress メソッドを通じて更新できます。publishProgress メソッドは、onProgressUpdate メソッドを呼び出します。また、タスクの結果は、onPostExecute メソッドに返されます。

3. onProgressUpdate(Object...values): このメソッドはメインスレッドで実行され、主にタスクの進捗状況が更新されるときに呼び出されます。

4. onPostExecute(Long aLong): メインスレッドで実行され、非同期タスクの実行後にこのメソッドが呼び出されます。このメソッドのパラメータはバックグラウンドの戻り結果です。

これらのメソッドに加えて、非同期タスクがキャンセルされたときに呼び出される onCancelled() など、あまり使用されないメソッドもいくつかあります。

ソース コードから、executeOnExecutor() メソッドが上記の実行メソッド内、つまり、executeOnExecutor(sDefaultExecutor, params) 内から呼び出され、sDefaultExecutor が実際にはシリアル スレッド プールであることがわかります。ここで onPreExecute() メソッドが呼び出されます。次にこのスレッド プールを見てください。 AsyncTask の実行は、キーワード synchronized によりキューに入れられ、AsyncTask の Params パラメーターは FutureTask クラスにカプセル化されます。FutureTask クラスは並行クラスであり、ここでは Runnable として機能します。次に、FutureTask は処理のために SerialExecutor の実行メソッドに渡され、SerialExecutor の実行メソッドは最初に FutureTask を mTasks キューに追加します。この時点でタスクがない場合は、scheduleNext() メソッドが呼び出されます。次のタスクを実行します。タスクが存在する場合、実行後の最後にscheduleNext();が呼び出され、次のタスクが実行されます。すべてのタスクが完了するまで。 AsyncTaskのコンストラクタにはcall()メソッドがあり、このメソッドはFutureTaskのrunメソッドによって実行されます。したがって、最終的にこの呼び出しメソッドはスレッド プールで実行されます。ここで doInBackground メソッドが呼び出されます。この call() メソッドを詳しく見てみましょう。 mTaskInvoked.set(true); は、現在のタスクが実行されたことを示します。次に、 doInBackground メソッドを実行し、最後に postResult(result); メソッドを通じて結果を渡します。 postResult()メソッドでは、sHandlerを介してメッセージが送信されますが、sHandlerではメッセージの種類によってMESSAGE_POST_RESULTが判定され、この場合はonPostExecute(result)メソッドまたはonCancelled(result)が呼び出されます。別のメッセージ タイプは MESSAGE_POST_PROGRESS で、onProgressUpdate を呼び出して進行状況を更新します。

Binder動作メカニズム

直感的に言えば、Binder は Android のクラスであり、IBinder インターフェイスを実装しています。IPC の観点から見ると、一般的に次のようになります。 Binder は Android のクロスプロセス通信の手段であり、仮想物理デバイスとしても理解でき、そのデバイス ドライバーは /dev/binder/ です。フレームワークの観点から見ると、Binder は ServiceManager のブリッジです。アプリケーション層から見ると、Binder はクライアントとサーバー間の通信の媒体です。

まず、このクラスの各メソッドの意味を理解しましょう:

DESCRIPTOR: Binder の一意の識別子。通常、現在の Binder クラス名を表すために使用されます。

asInterface(android.os.IBinder obj): サーバーの Binder オブジェクトを、クライアントが必要とする AIDL インターフェイス タイプのオブジェクトに変換するために使用されます。この変換プロセスはプロセス固有です。クライアントとサービスの場合、クライアントが同じプロセス内にある場合、このメソッドはサーバーのスタブ オブジェクト自体を返します。それ以外の場合は、システムでカプセル化された Stub.proxy オブジェクトを返します。

asBinder(): 現在の Binder オブジェクトを返すために使用されます。

onTransact: このメソッドは、サーバー側のバインダー スレッド プールで実行されます。クライアントがプロセス間通信リクエストを開始すると、リモート リクエストはシステムの最下層によってカプセル化され、このメソッドに渡されます。加工用に。このメソッド public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel Reply, int flags) に注意してください。サーバーは、コードを通じてクライアントによって要求されたターゲット メソッドを決定し、ターゲットを取得できます。データからメソッドに必要なパラメータを取得し、ターゲット メソッドを実行します。対象のメソッドが実行されると、戻り値がリプライに書き込まれます。このようにしてメソッドが実行されます。このメソッドが false を返す場合、クライアントはリクエストに失敗するため、このメソッドでセキュリティ検証を行うことができます。

Binder の動作メカニズムでは、いくつかの問題に注意する必要があります。 1. クライアントがリクエストを開始するとき、現在のスレッドは、サーバーがデータを返すまで中断されます。このリモート メソッドが非常に時間がかかる場合、このリモート リクエストは UI スレッド、つまりメイン スレッドで開始できません。

2. Service の Binder メソッドはスレッド プールで実行されるため、時間がかかるかどうかにかかわらず、Binder メソッドはすでにスレッドで実行されているため、同期する必要があります。

view イベント配信と view 動作原理

Android カスタム ビュー、誰もが知っています。実装には、onMeasure()、onLayout()、onDraw() の 3 つの部分があることがわかります。 Viewの描画処理はviewRootのperfromTraversalメソッドから始まります。測定、レイアウト、描画メソッドを通じてビューを描画できます。このうち、measure は幅と高さを測定し、layout は親コンテナ上のビューの位置を決定し、draw はビューを画面に描画します。

Measure:

View 測定には、32 ビットの int 値を表す MeasureSpc (測定仕様) が必要です。上位 2 ビットは SpecMode (測定モード) を表し、下位 (30) ビットは SpecSize (特定の測定モードでの仕様サイズ) を表します。 SpecMode と SpeSize のセットを MeasureSpec にパッケージ化することも、逆に MeasureSpec をアンパックして SpecMode と SpeSize の値を取得することもできます。 SpecMode には 3 つのタイプがあります。

unSpecified: 親コンテナには、ビューの大きさに関係なく、ビューに対する制限がありません。一般的なシステムでよく使われます。

正確: 親コンテナは、ビューに必要な正確なサイズを検出しました。この時点で、ビューのサイズは、レイアウト レイアウトの math_parent または特定の値に対応する SpecSize で指定された値です

At_most :親コンテナは、利用可能なサイズの SpecSize を指定します。ビューのサイズは、この値より大きくすることはできません。これは、このレイアウトの wrao_content に対応します。

通常のビューの場合、その MeasureSpec は構成されます親コンテナの MeasureSpec とそれ自体のlayoutParam が一緒に決定され、一度 MeasureSpec が決定されると、onMeasure はビューの幅と高さを決定できます。

ビューの測定プロセス:

onMeasure メソッドには、ビューの幅と高さの測定値を設定する setMeasureDimenSion メソッドがあり、setMeasureDimenSion にはパラメーターとして getDefaultSize() メソッドがあります。通常の状況では、at_most と正確な状況にのみ注意を払う必要があります。getDefaultSize の戻り値は、measureSpec の SpecSize であり、この値は基本的にビューの測定サイズです。 UnSpecified の場合、通常はシステム内の測定プロセスであり、ビューの背景などの要素を考慮する必要があります。

先ほど説明したのは、view の測定プロセスと viewGroup の測定プロセスです。

viewGroup の場合、独自の測定プロセスを完了するだけでなく、呼び出すためにトラバースする必要もあります。 viewGroup は、onMeasure メソッドを提供せず、measureChildren メソッドを提供する抽象クラスです。 measureChild メソッドの考え方は、子要素のlayoutParams を取り出し、getChildMeasureSpec を通じて子要素の MeasureSpec を取得し、電気泳動測定メソッドで子要素を測定することです。 viewGroup のサブクラスはレイアウトメソッドが異なるため、測定内容も異なります。そのため、viewGroup は view のように測定用の onMeasure メソッドを呼び出すことができません。

注: ビューが測定されていないため、アクティビティのライフサイクル中にビューの幅と高さを正しく取得する方法はありません。

  1. onWindowFocuschanged メソッドで取得 ---- 変更されたメソッドの意味は、ビューが初期化されたことです。
  2. View.post() メソッドは、メッセージを配信します。メッセージキューの終わり。
  3. viewTreeObserver のコールバックを使用して完了します。
  4. view.measure を通じて手動で測定します。

onLayout

通常のビューの場合、setFrame メソッドを使用してビューの 4 つの頂点の位置を取得でき、これにより位置も決定されます。親コンテナ内のビューの位置を指定してから、親コンテナから子要素の位置を決定する onLayout メソッドを呼び出します。

onDraw

このメソッドは、ビューを画面に描画します。次のステップに分けます:

  1. 背景を描く、
  2. 自分自身を描く、
  3. 子供を描く、
  4. 装飾を描く。

Androidパフォーマンスの最適化

携帯電話ハードウェアの制限により、メモリも CPU もそれほど大きな容量を持つことができません。 Android スマートフォンでは、メモリの過剰な使用が容易に OOM につながる可能性があり、CPU リソースの過剰な使用により、スマートフォンがフリーズしたり、Anr が発生したりする可能性があります。主に次の部分から最適化します。

レイアウトの最適化、描画の最適化、メモリ リークの最適化、応答速度の最適化、リストビューの最適化、ビットマップの最適化、スレッドの最適化

レイアウトの最適化: ツール階層ビューアー、解決策:

1. 不要なスペースとレベルを削除します。

2. Relativelayout など、パフォーマンスの低いビューグループを選択します。Relativelayout または LinearLayout を選択できる場合は、Relativelayout の機能が比較的複雑で、より多くの CPU リソースを占有するため、最初に LinearLayout を使用してください。

3. タグ 2b2ce02883c1666e919b0f20335eaf2a を使用してレイアウトを再利用し、2a6fb28f9e61d01de7fd925ea9f58d4d でレベルを下げ、fecc3e51a9f4ddea0b0a0fe6cfb27c34 をプリロードし、使用する場合にのみロードします。

描画の最適化

描画の最適化とは、ondraw メソッドが頻繁に呼び出される可能性があるため、ビューが ondraw メソッドでの時間のかかる多数の操作を回避することを意味します。

1. ondraw メソッドでは新しいローカル変数を作成しないでください。ondraw メソッドは頻繁に呼び出されるため、GC が発生しやすくなります。

2. ondraw メソッドでは時間のかかる操作を実行しないでください。

メモリの最適化: メモリ リークを参照してください。

応答の最適化: メインスレッドは時間のかかる操作を実行できません。タッチイベントには 5 秒、ブロードキャストには 10 秒、サービスには 20 秒かかります。

リストビューの最適化:

1. getview メソッドでの時間のかかる操作を避けてください。

2. ビューの再利用とビューホルダーの使用。

3. スライドは非同期読み込みを有効にするのには適していません。

4. ページングによってデータを処理します。

5. 画像はレベル 3 キャッシュを使用します。

ビットマップの最適化:

1. 画像を同じ比率で圧縮します。

2. リサイクラーは未使用の画像を時間内に処理します

スレッドの最適化

スレッドの最適化の考え方は、スレッド プールを使用してスレッドを管理および再利用し、大量のスレッドが発生するのを避けることです。スレッドは、リソースの相互プリエンプションによるスレッドのブロックを回避するために、同時スレッドの数を制御することもできます。

その他の最適化

1. 多くのスペースを占有する列挙の使用を減らします。

2. hashMap の代わりに SparseArray などの Android 固有のデータ構造を使用します。

3. ソフト参照と弱い参照を適切に使用します。

暗号化アルゴリズム (base64MD5、対称暗号化および非対称暗号化) と使用シナリオ。

Rsa 暗号化とは何ですか?

RSA アルゴリズムは、長さが異なるキーを使用する最も一般的な公開キー暗号化アルゴリズムです。 RSA は、データ暗号化とデジタル署名の両方に使用できる最初のアルゴリズムです。

RSA アルゴリズムの原理は次のとおりです:

1. 2 つの大きな素数 p と q (p は q に等しくありません) をランダムに選択し、N=pq を計算します。

2. より大きい数を選択してください 1 が N より小さい場合、自然数 e は (p-1)(q-1) と互いに素でなければなりません。

3. 次の式を使用して d を計算します: d×e = 1 (mod (p-1)(q-1))。

4. p と q を破棄します。

最後の N と e は「公開キー」、d は「秘密キー」です。送信者は N を使用してデータを暗号化し、受信者は d を使用してデータの内容を復号化することのみができます。

RSA のセキュリティは、大きな数値分解に依存しています。1024 ビットより小さい N は安全ではないことが証明されています。さらに、RSA アルゴリズムは大きな数値計算を実行するため、RSA は最速でも DES より高速です。1 倍遅いです。 、これは RSA の最大の欠陥であるため、通常は少量のデータまたは暗号化キーの暗号化にしか使用できませんが、RSA は依然として強度の高いアルゴリズムです。

使用シナリオ: プロジェクトでは、ログイン、支払い、その他のインターフェイスを除き、rsa 非対称暗号化が使用され、他のインターフェイスには aes 対称暗号化が使用されます。今日は aes 暗号化について学習します。

MD5 暗号化とは何ですか?

MD5 の完全な英語名は「Message-Digest Algorithm 5」で、「メッセージ ダイジェスト アルゴリズム 5」と訳されます。MD2、MD3、MD4 から進化したもので、一方向の暗号化アルゴリズムです。不可逆的な暗号化方式。

MD5 暗号化の特徴は何ですか?

圧縮率: データの長さに関係なく、計算された MD5 値の長さは固定されます。

計算が簡単: 元のデータから MD5 値を計算するのは簡単です。

変更に対する耐性: 元のデータに変更が加えられた場合、たとえ 1 バイトだけが変更されたとしても、結果の MD5 値は大きく異なります。

強力な衝突防止: 元のデータとその MD5 値がわかっていると、同じ MD5 値を持つデータ (つまり、偽造データ) を見つけるのは非常に困難です。

MD5 アプリケーション シナリオ:

一貫性検証

デジタル署名

安全なアクセス認証

aes 暗号化とは何ですか?

Advanced Encryption Standard(英語: Advanced Encryption Standard、略称: AES)は、暗号学におけるラインダール暗号化方式とも呼ばれ、米国連邦政府によって採用されたブロック暗号化規格です。この標準はオリジナルの DES を置き換えるために使用され、多くの関係者によって分析され、世界中で広く使用されています。

HashMap の実装原理:

HashMap は、ハッシュ テーブルに基づくマップ インターフェイスの非同期実装であり、キーと値として null 値を使用できます。 Java プログラミング言語には 2 つの最も基本的な構造があり、1 つは配列、もう 1 つはシミュレートされたポインター (参照) です。すべてのデータ構造は、これら 2 つの基本構造を使用して構築できます。HashMap も例外ではありません。 HashMap は実際には「リンク リスト ハッシュ」データ構造です。配列とリンクリストを組み合わせたものです。

HashMap の最下層はデータ構造であり、配列内の各項目はリンク リストです。

競合:

Java の 2 つの異なるオブジェクトが同じハッシュコードを持つ可能性があるため、HashMap で Hashcode() メソッドが呼び出され、Hashclde 値が計算されます。これが紛争につながりました。

解決策:

HashMap を配置すると、基になるソース コードから、プログラムがキーと値のオブジェクトを HashMap に配置しようとすると、最初に値に基づいた値が返されることがわかります。キーの hashCode() を調べます。エントリの格納場所を決定します。2 つのエントリ キーの hashCode() メソッドの戻り値が同じ場合、それらの格納場所は同じです。2 つのエントリ キーが true を返した場合、等しい比較の場合、新しく追加されたエントリの値は元のエントリの値を上書きしますが、キーは上書きされません。逆に false が返された場合、新しく追加されたエントリは元のエントリとのエントリ チェーンを形成しますコレクション内で、新しく追加されたものが先頭、古いものが末尾になります

HashMap の実装原則:

    キーの hashCode を使用して再ハッシュして計算します配列内の現在のオブジェクトの要素の添え字。
  1. 同じハッシュ値を持つキーが保存中に出現した場合、次の 2 つの状況が考えられます。 1. キーが同じ場合、元の値は上書きされます。 2. キーが異なる (競合が発生する) 場合は、それらをリンク リストに追加します。
  2. 取得する際は、ハッシュ値に対応する添字を直接検索し、さらにキーが同一かどうかを判定することで、対応する値を取得します。
  3. Hashmap の核心は、配列を保存に使用することであり、キーの競合が発生すると、リンクされたリストに保存されます。
============================

1. アクティビティのライフサイクル?

onCreate() ->onStart() ->onResume() ->onPause() ->onStop() ->onDetroy()

2. サービスのライフサイクル?

サービスを開始するには 2 つの方法があります。1 つは startService() を使用して開始する方法、もう 1 つは bindingService() を使用して開始する方法です。起動方法が異なれば、ライフサイクルも異なります。

startService() を通じて開始されるサービスのライフ サイクルは次のとおりです: startService() -->onCreate()-->onStartConmon()-->onDestroy() を呼び出します。この方法で開始する場合、いくつかの問題に注意する必要があります。最初に、startService を通じて呼び出されるときに、startService() を複数回呼び出すと、onCreate() メソッドは 1 回だけ呼び出され、onStartConmon() は呼び出されます。 stopService() を呼び出すと、サービスを破棄するために onDestroy() が呼び出されます。 2 番目: startService を通じて開始し、インテントを通じて値を渡し、onStartConmon() メソッドで値を取得するとき、最初にインテントが null かどうかを判断する必要があります。

bindingService() を介してバインドします。サービス、ライフサイクル メソッドをバインドするこの方法:bindService-->onCreate()-->onBind()-->unBind()- ->onDestroy( ) bingservice この方法でサービスを開始する利点は、アクティビティ内でサービスを操作する方が便利であることです。たとえば、サービスに参加するには、a、b のいくつかの方法があります。アクティビティ内で呼び出したい場合は、 , アクティビティで ServiceConnection オブジェクトを取得する必要があります。ServiceConnection を使用してサービスの内部クラスのクラス オブジェクトを取得し、このクラス オブジェクトを使用してクラス内のメソッドを呼び出します。もちろん、このクラスは Binder を継承する必要がありますobject

3. アクティビティの起動プロセス (ライフサイクルには答えません)

アプリの起動プロセスには 2 つの状況があります。1 つ目は、デスクトップ ランチャーから対応するアプリケーションのアイコンをクリックすることです。 2 つ目は、アクティビティ内で startActivity を呼び出して新しいアクティビティを開始することです。

新しいプロジェクトを作成すると、デフォルトのルート アクティビティは MainActivity になり、すべてのアクティビティがスタックに保存されます。新しいアクティビティを開始すると、前のアクティビティの上に配置され、いつでもデスクトップからアプリケーション アイコンをクリックすると、ランチャー自体もアプリケーションであるため、アイコンをクリックすると、システムは startActivitySately() を呼び出します。通常の状況では、開始したアクティビティの関連情報はインテントに保存されます。アクション、カテゴリなど。このアプリケーションをインストールすると、システムは PackaManagerService 管理サービスも開始します。この管理サービスは、AndroidManifest.xml ファイルを解析して、アプリケーション内の関連情報 (サービス、アクティビティ、ブロードキャストなど) を取得し、その後、次の情報を取得します。関連コンポーネント。アプリケーション アイコンをクリックすると、startActivitySately() メソッドが呼び出され、このメソッド内で startActivty() が呼び出され、最終的に startActivity() メソッドが startActivityForResult() メソッドを呼び出します。そして startActivityForResult() メソッド内です。 startActivityForResult() メソッドは結果を返すため、システムは直接 -1 を返します。これは、結果を返す必要がないことを意味します。 startActivityForResult() メソッドは、Instrumentation クラスの execStartActivity() メソッドを通じて実際にアクティビティを開始します。Instrumentation クラスの主な機能は、プログラムとシステム間の対話を監視することです。この execStartActivity() メソッドでは、ActivityManagerService のプロキシ オブジェクトが取得され、このプロキシ オブジェクトを通じてアクティビティが開始されます。 A checkStartActivityResult() メソッドは起動時に呼び出されます。このコンポーネントが構成リストに構成されていない場合、このメソッドで例外がスローされます。もちろん、最後の呼び出しは、アクティビティを開始する Application.scheduleLaunchActivity() です。このメソッドでは、ActivityClientRecord オブジェクトが取得され、この ActivityClientRecord はハンドラーを使用してメッセージを送信します。内部的には、システムは各アクティビティ コンポーネントに対して ActivityClientRecord オブジェクトを使用します。 .Description、ActivityClientRecord オブジェクトには LoaderApk オブジェクトが格納されており、このオブジェクトを通じて handleLaunchActivity が呼び出されてアクティビティ コンポーネントが開始され、ページのライフサイクル メソッドがこのメソッドで呼び出されます。

4. ブロードキャストの登録方法と違い

ここでの拡張: 動的登録を使用する場合

ブロードキャスト ブロードキャストには、2 つの主要な登録方法があります。

1 つ目は静的登録で、常駐ブロードキャストにもなります。この種のブロードキャストは Androidmanifest.xml に登録する必要があります。この方法で登録されたブロードキャストはページのライフサイクルの影響を受けません。ページを終了しても、まだブロードキャストの受信は、コンピュータを自動的に起動したい場合などによく使用されます。この登録方法のブロードキャストは常時ブロードキャストであるため、CPU リソースを占有します。

2 番目のタイプは動的登録であり、動的登録はコード内で登録されます。この登録方法は非常駐ブロードキャストとも呼ばれます。ライフサイクルの影響を受けます。ページを終了すると、その後は反映されません。ブロードキャストを受信すると、通常はそれを使用して UI を更新します。この登録方法が優先されます。最後に、メモリ リークが発生するかどうかにかかわらず、バインドを解除する必要があります。

ブロードキャストは、順序付きブロードキャストと順序なしブロードキャストに分けられます。

5. HttpClient と HttpUrlConnection の違い

ここでの拡張子: Volley で使用されるリクエスト メソッド (2.3 より前の HttpClient、2.3 以降の HttpUrlConnection)

まず第一に、HttpClient と HttpUrlConnection は両方とも Https プロトコルをサポートしています。どちらもストリームの形式でデータをアップロードまたはダウンロードします。ストリームの形式でデータを送信することも、ipv6、コネクション プーリングなどと同様に言えます。機能。 。 HttpClient は API が多く、互換性を崩さずに拡張しようとすると拡張が難しく、このため Google は Android 6.0 でこの HttpClient を直接放棄しました。 、API が比較的少なく、拡張が容易で、Android のほとんどのデータ転送に対応できます。 Volley は比較的古典的なフレームワークであり、バージョン 2.3 より前は HttpClient を使用し、バージョン 2.3 以降は HttpUrlConnection を使用していました。

6. Java 仮想マシンと Dalvik 仮想マシンの違い

Java 仮想マシン:

1. Java 仮想マシンはスタックに基づいています。スタックベースのマシンは、命令を使用してスタック上のデータをロードして操作する必要があり、さらに多くの命令が必要です。

2. Java 仮想マシンは Java バイトコードを実行します。 (Java クラスは 1 つ以上のバイトコード .class ファイルにコンパイルされます)

Dalvik 仮想マシン:

1. dalvik 仮想マシンはレジスタベースです

2 、 Dalvik はカスタム .dex バイトコード形式を実行します。 (Java クラスが .class ファイルにコンパイルされた後、dx ツールを使用してすべての .class ファイルが .dex ファイルに変換され、その後、dalvik 仮想マシンがそこから命令とデータを読み取ります

3. 定数プール インタプリタを簡素化するために 32 ビット インデックスのみを使用するように変更されました

4. 1 つのアプリケーション、1 つの仮想マシン インスタンス、および 1 つのプロセス (すべての Android アプリケーション スレッドが 1 つの Linux スレッドに対応します) 、すべて独自のサンドボックスで実行され、異なるアプリケーションは異なるプロセスで実行されます。各 Android dalvik アプリケーションには、独立した Linux PID が与えられます (app_*))

7. プロセスのキープ アライブ (アンデッド プロセス)

ここに拡張: プロセスの優先順位は何ですか

現在の業界の Android プロセスのキープアライブ方式は主に黒、白、グレーの 3 種類に分かれており、大まかな実装の考え方は次のとおりです。

ブラック キープアライブ: さまざまなアプリ プロセスがブロードキャストを使用して相互にウェイクアップします (システムによって提供されるブロードキャストを使用してウェイクアップすることを含む)

ホワイト キープアライブ: フォアグラウンド サービスを開始します

グレーのキープアライブ: システムの脆弱性を利用してフロントエンド サービスを開始します

ブラック キープアライブ

いわゆるブラック キープアライブは、さまざまなアプリ プロセスを使用して、ブロードキャストを使用して相互にウェイクアップします。以下に 3 つの比較を示します。 一般的なシナリオ:

シナリオ 1: 電話の電源を入れる、ネットワークを切り替える、写真を撮る、またはビデオを撮影するときに、システムによって生成されたブロードキャストを使用してウェイクアップします。アプリ

シナリオ 2: サードパーティ SDK に接続すると、対応するアプリのアプリ プロセスも起動されます (例: WeChat SDK は WeChat を起動し、Alipay SDK は Alipay を起動します)。次のシナリオを直接トリガーします 3

シナリオ 3: 携帯電話、Tmall、UC、およびその他の Alibaba ベースのアプリに Alipay と Taobao がインストールされている場合、Alibaba ベースのアプリを開いた後、スリープ解除される可能性がありますちなみに、その他の Alibaba ベースのアプリ (Alibaba を例として使用しているだけですが、実際には BAT システムも同様です)

ホワイト キープアライブ

ホワイト キープアライブ メソッドは非常に優れています。シンプルです。システム API を呼び出してフォアグラウンド サービス プロセスを開始します。これにより、システム通知バーに通知が生成され、現在のアプリがバックグラウンドに戻った場合でも、そのようなアプリが実行中であることがユーザーに通知されます。たとえば、以下の LBE と QQ Music:

Gray Keep Alive

Gray Keep Alive、このキープアライブ メソッドは、最も広い適用範囲を持つアプリケーションであり、システムの脆弱性を利用してフォアグラウンドを開始します。サービス プロセス。通常の起動方法との違いは、システム通知バーに通知が表示されず、バックグラウンドでサービス プロセスが実行されているように見えることです。この利点は、ユーザーが実行中であることを検出できないことです。 (通知が表示されないため) フォアグラウンド プロセスですが、プロセスの優先順位は通常のバックグラウンド プロセスよりも高くなります。では、システムの脆弱性を悪用するにはどうすればよいでしょうか? 一般的な実装のアイデアとコードは次のとおりです:

アイデア 1: API

アイデア2 : API >= 18、同じ ID で 2 つのフロントエンド サービスを同時に開始し、後で開始されたサービスを停止します

Android システムに詳しい人なら、このシステムがベースであることを知っています。エクスペリエンスとパフォーマンスの考慮事項。アプリがバックグラウンドに戻ったときにシステムは実際にプロセスを強制終了せず、キャッシュします。開くアプリケーションが増えるほど、バックグラウンドでキャッシュされるプロセスも増えます。システム メモリが不十分な場合、システムは、必要なアプリを提供するためにメモリを解放するために、独自のプロセス リサイクル メカニズムのセットに基づいてどのプロセスを強制終了するかを決定し始めます。プロセスを強制終了してメモリを再利用するこのメカニズムは、Low Memory Killer と呼ばれ、Linux カーネルの OOM Killer (Out-Of-Memory Killer) メカニズムに基づいています。

プロセスの重要度は 5 つのレベルに分類されます。

フォアグラウンド プロセス

目に見えるプロセス

サービス プロセス )

バックグラウンド プロセス

空のプロセス

Low Memory Killer を理解した後、oom_adj についてさらに学びましょう。 oom_adj とは何ですか?これは、Linux カーネルによって各システム プロセスに割り当てられる、プロセスの優先度を表す値であり、プロセスのリサイクル機構はこの優先度に基づいてリサイクルするかどうかを決定します。 oom_adj の役割に関しては、次の点だけを覚えておく必要があります:

プロセスの oom_adj が大きいほど、プロセスの優先順位は低くなり、強制終了およびリサイクルされやすくなります。 oom_adj、プロセスの優先度が高くなります。値が大きいほど、プロセスが強制終了され、リサイクルされる可能性が低くなります。

通常のアプリ プロセスの oom_adj >=0、システム プロセスの oom_adj のみが許可されます。

一部の携帯電話メーカーは、これらの有名なアプリを自社のホワイト リストに組み込んでおり、ユーザー エクスペリエンスを向上させるためにプロセスが停止しないようにしています (WeChat、QQ、Momo などはすべてXiaomi のホワイトリストに含まれています)。ホワイトリストから外されても通常のアプリと同様に殺される運命からは逃れられるので、できるだけ殺されないようにするためには愚直に最適化作業をしたほうが良いでしょう。

したがって、プロセスを存続させるための根本的な解決策は、最終的にはパフォーマンスの最適化に戻ります。プロセスの不滅性は結局のところ、完全な間違った命題です。

8. コンテキストの説明

Context は抽象基本クラスです。コンテキストとして翻訳されると、一部のプログラムの実行環境に関する基本情報を提供する環境としても理解されます。 Context の下には 2 つのサブクラスがあり、ContextWrapper はコンテキスト関数のカプセル化クラス、ContextImpl はコンテキスト関数の実装クラスです。 ContextWrapper には、ContextThemeWrapper、Service、Application という 3 つの直接のサブクラスがあります。このうち、ContextThemeWrapper はテーマを持ったカプセル化クラスであり、その直接のサブクラスの 1 つが Activity であるため、Activity、Service、Application の Context が異なりますが、Activity のみテーマが必要で、Service はテーマを必要としません。コンテキストには、アプリケーション、アクティビティ、サービスという 3 つのタイプがあります。これら 3 つのクラスは異なる役割を果たしますが、これらはすべて 1 つのタイプの Context に属しており、その特定の Context 関数は ContextImpl クラスによって実装されるため、ほとんどのシナリオでは、Activity、Service、および Application のこれら 3 つのタイプの Context はすべて普遍的です。ただし、アクティビティの開始やダイアログのポップアップなど、いくつかの特殊なシナリオがあります。セキュリティ上の理由から、Android ではアクティビティやダイアログがどこからともなく現れることを許可していません。アクティビティの起動は、これによって形成されるリターン スタックである別のアクティビティに基づいて行う必要があります。ダイアログはアクティビティ上にポップアップする必要があるため (システム アラート タイプのダイアログでない限り)、このシナリオではアクティビティ タイプのコンテキストのみを使用できます。それ以外の場合はエラーが発生します。

getApplicationContext() メソッドと getApplication() メソッドで取得したオブジェクトは同じアプリケーション オブジェクトですが、オブジェクトの種類が異なります。

コンテキストの数 = アクティビティの数 サービスの数 1 (1 はアプリケーション)

9. アクティビティ、ビュー、ウィンドウの関係を理解する

この質問は実際に答えるのは難しいです。そこで、彼らの関係を説明するためのより適切な比喩を次に示します。 Activity は職人 (制御ユニット)、Window はウィンドウ (モデルを運ぶ)、View はウィンドウ グリル (ビューを表示)、LayoutInflater はハサミ、Xml 構成はウィンドウ グリルの描画のようなものです。

1: Activity が構築されると、Window (正確には PhoneWindow) が初期化されます。

2: この PhoneWindow には「ViewRoot」があり、この「ViewRoot」は初期ルート ビューである View または ViewGroup です。

3: 「ViewRoot」は、addView メソッドを通じて View を 1 つずつ追加します。たとえば、TextView、Button などです。

4: これらのビューのイベント監視は、メッセージを受信して​​アクティビティ関数をコールバックするために WindowManagerService によって行われます。たとえば、onClickListener、onKeyDown などです。

10. 4 つの LaunchModes とその使用シナリオ

ここでの拡張: スタック (先入れ後出し) とキュー (先入れ先出し) の違い

スタックとキュー間の違い:

1. キューは先入れ先出し、スタックは先入れ後出しです。

2. 挿入および削除操作の「制限」。スタックは、挿入および削除操作をリストの一端のみに制限する線形リストです。キューは、テーブルの一方の端への挿入ともう一方の端への削除を制限する線形リストです。

3. データの移動速度が異なります

標準モード

これはデフォルトのモードです。アクティビティがアクティブ化されるたびに、アクティビティ インスタンスが作成され、配置されます。タスクスタック。使用シナリオ: ほとんどのアクティビティ。

singleTop モード

タスク スタックの最上位にアクティビティのインスタンスがある場合、そのインスタンスは再利用されます (インスタンスの onNewIntent() が呼び出されます)。そうでない場合は、新しいインスタンスが作成されて配置されます。スタックの先頭にプッシュすると、アクティビティのインスタンスがスタック上にすでに存在する場合でも、スタックの先頭にない限り、新しいインスタンスが作成されます。使用シナリオには、ニュースや読書アプリのコンテンツ ページが含まれます。

singleTask モード

スタック内に既にアクティビティのインスタンスがある場合、そのインスタンスは再利用されます (インスタンスの onNewIntent() が呼び出されます)。再利用されると、インスタンスはスタックの先頭に戻されるため、その上のインスタンスはスタックから削除されます。インスタンスがスタック上に存在しない場合は、新しいインスタンスが作成され、スタック上に配置されます。利用シーンはブラウザのメインインターフェースなどです。どれだけ多くのアプリケーションからブラウザを起動しても、メインインターフェースは一度しか起動されず、それ以外の場合はonNewIntentが使用され、メインインターフェース上の他のページはクリアされます。

singleInstance モード

新しいスタックにアクティビティのインスタンスを作成し、複数のアプリケーションがスタック内のアクティビティ インスタンスを共有できるようにします。このモードのアクティビティ インスタンスがスタック内にすでに存在すると、アクティビティをアクティブ化するアプリケーションはスタック内のインスタンスを再利用します (インスタンスの onNewIntent() が呼び出されます)。この効果は、複数のアプリケーションが 1 つのアプリケーションを共有しているのと同等であり、誰がアクティビティをアクティブ化しても、同じアプリケーションに入ります。アラーム リマインダーなどのシナリオを使用して、アラーム リマインダーをアラーム設定から分離します。中間ページには singleInstance を使用しないでください。中間ページに使用すると、A -> B (singleInstance) -> C などのジャンプで問題が発生します。完全に終了した後、ここから開始すると、B が最初に開きます。 。

11. 描画プロセスの表示

カスタム コントロール:

1. 組み合わせたコントロール。この種のカスタム コントロールは、自分で描画する必要はなく、ネイティブ コントロールで構成される新しいコントロールを必要とします。タイトルバーなど。

2. 元のコントロールを継承します。この種のカスタム コントロールは、ネイティブ コントロールによって提供されるメソッドに加えて、いくつかのメソッドを独自に追加できます。角を丸くしたり、円形の絵を作るなど。

3. 完全にカスタマイズされたコントロール: このビューに表示されるすべてのコンテンツは私たち自身が描画したものです。たとえば、水の波紋の進行状況バーを作成します。

ビューの描画プロセス: OnMeasure()——>OnLayout()——>OnDraw()

最初のステップ: OnMeasure(): ビューのサイズを測定します。測定メソッドは最上位の親 View から子 View へ再帰的に呼び出され、測定メソッドは OnMeasure をコールバックします。

ステップ 2: OnLayout(): ビューの位置を決定し、ページをレイアウトします。最上位の親 View から子 View へ view.layout メソッドを再帰的に呼び出すプロセスは、親 View が、レイアウト サイズと、子 View を測定して取得したレイアウト パラメータに基づいて、子 View を適切な位置に配置することを意味します。一つ前の手順。

ステップ 3: OnDraw(): ビューを描画します。 ViewRoot は Canvas オブジェクトを作成し、OnDraw() を呼び出します。 6 つのステップ: ①、ビューの背景を描画します; ②、キャンバス レイヤ (レイヤー) を保存します; ③、ビューのコンテンツを描画します; ④、ビュー サブビューを描画します (そうでない場合は使用しないでください)

⑤、レイヤーを復元、⑥、スクロールバーを描画します。

12. View イベントと ViewGroup イベントは

1 に分割されます。Touch イベント配布の主役は ViewGroup と View の 2 人だけです。 ViewGroup には、onInterceptTouchEvent、dispatchTouchEvent、および onTouchEvent という 3 つの関連イベントが含まれています。ビューには、dispatchTouchEvent と onTouchEvent という 2 つの関連イベントが含まれています。このうち、ViewGroupはViewを継承しています。

2. ViewGroup と View はツリー構造を形成し、ルート ノードはアクティビティ内に含まれる ViwGroup です。

3. タッチ イベントは、Action_Down、Action_Move、および Aciton_UP で構成されます。完全なタッチ イベントには、Down と Up が 1 つだけあり、Move が複数あり、0 になる可能性があります。

4. Acitivty が Touch イベントを受信すると、サブビューを走査して Down イベントを配布します。 ViewGroup のトラバーサルは再帰的であるとみなすことができます。配布の目的は、この完全なタッチ イベントを実際に処理するビューを見つけることであり、このビューは onTouchEvent の結果で true を返します。

5. サブビューが true を返すと、Down イベントの配信が停止され、サブビューが ViewGroup に記録されます。後続の Move および Up イベントは、サブビューによって直接処理されます。サブ View は、多層 ViewGroup ノード構造の ViewGroup に保存されるため、上位レベルの ViewGroup は、実際にイベントを処理する View が配置される ViewGroup オブジェクトを保存します。たとえば、ViewGroup0-ViewGroup1 の構造に保存されます。 -TextView、TextView は true を返し、ViewGroup1 に保存されます。ViewGroup1 も true を返し、ViewGroup0 に保存されます。 Move および UP イベントが発生すると、それらはまず ViewGroup0 から ViewGroup1 に渡され、次に ViewGroup1 から TextView に渡されます。

6. ViewGroup 内のすべてのサブビューが Down イベントをキャプチャしない場合、ViewGroup 自体の onTouch イベントがトリガーされます。トリガーする方法は、親クラス View のdispatchTouchEvent メソッドである super.dispatchTouchEvent 関数を呼び出すことです。すべてのサブビューが処理されない場合、Activity の onTouchEvent メソッドがトリガーされます。

7.onInterceptTouchEvent には 2 つの機能があります。 1. Down イベントの配信をインターセプトします。 2. ターゲット ビューへの Up および Move イベントの配信を停止し、ターゲット ビューが配置されている ViewGroup が Up および Move イベントをキャプチャできるようにします。

13. アクティビティ状態の保存

onSaveInstanceState(Bundle) は、アクティビティがバックグラウンド状態に入る前、つまり、onStop() メソッドの前と onPause メソッドの後に呼び出されます。

14. Android のいくつかのアニメーション

フレーム アニメーション: 聞きたいリズム バーなどのアニメーション効果を形成する、画像と各フレームの再生時間を順番に再生することを指します。

トゥイーン アニメーション: ビューの初期状態、変更時間、メソッドを指定して一連のアルゴリズムを通じてグラフィック変換を実行し、アニメーション効果を形成することを指します。主に 4 つの効果があります: Alpha、Scale、Translate 、回転します。注: アニメーション効果はビュー レイヤにのみ実装され、リストのスライドやタイトル バーの透明度の変更など、ビューのプロパティは実際には変更されません。

属性アニメーション: Android 3.0 でのみサポートされています。アニメーション効果は、ビューの属性を継続的に変更し、継続的に再描画することによって形成されます。ビュー アニメーションと比較すると、ビューのプロパティは実際に変更されます。たとえば、ビューの回転、ズームイン、ズームアウトなどです。

15. Android におけるクロスプロセス通信のいくつかの方法

Android のクロスプロセス通信 (インテント、contentProvider、ブロードキャスト、サービスなど) はすべて、プロセス間で通信できます。

意図: このクロスプロセス メソッドはメモリ アクセスの形式ではなく、呼び出しを行うなど、URI を渡す必要があります。

contentProvider: このフォームはデータ共有にデータ共有を使用します。

service: リモート サービス、aidl

broadcast

16. AIDL の理解

ここでの拡張: Binder の簡単な説明

AIDL:各プロセスは独自の Dalvik VM インスタンスを持ち、独自の独立したメモリを持ち、独自のデータを独自のメモリに保存し、独自の操作を実行し、独自の小さなスペースで独自の生活を完了します。 Aidl は 2 つのプロセス間のブリッジのようなもので、2 つのプロセス間でデータを送信できるようにします。BroadcastReceiver、Messenger など、プロセス間通信には多くのオプションがありますが、BroadcastReceiver はより多くのシステム リソースを消費します。プロセス通信は明らかに推奨されません。Messenger がプロセス間通信を実行する場合、リクエスト キューは同期的に実行され、同時に実行することはできません。

バインド メカニズムの簡単な理解:

Android システムのバインダ メカニズムでは、クライアント、サービス、サービス マネージャー、およびバインダー ドライバーで構成されます。ユーザー空間で実行される場合、Binder ドライバーはカーネル空間で実行されます。 Binder は、これら 4 つのコンポーネントを結合する接着剤です。コア コンポーネントは Binder ドライバーです。Service Manager は補助的な管理機能を提供し、Client と Service は Binder ドライバーと Service Manager に基づいています。施設上の C/S 間の通信を実装します。バインダー ドライバーは、ユーザー コントロールと対話するためのデバイス ファイル /dev/binder を提供します。

クライアント、サービス、およびサービス マネージャーは、open および ioctl ファイル操作の対応するメソッドを通じてバインダー ドライバーと通信します。クライアントとサービス間のプロセス間通信は、Binder ドライバーを通じて間接的に実装されます。バインダー マネージャーは、サービスを管理し、クライアントにサービス インターフェイスをクエリする機能を提供するデーモン プロセスです。

17. ハンドラーの原理

Android では、メインスレッドは時間のかかる操作を実行できず、子スレッドは UI を更新できません。したがって、ハンドラーがあり、その役割はスレッド間の通信を実装することです。

handler プロセス全体には、handler、Message、MessageQueue、Looper という 4 つの主要なオブジェクトがあります。アプリケーションが作成されると、メイン スレッドでハンドラー オブジェクトが作成されます。

メッセージに送信するメッセージを保存します。ハンドラーは、sendMessage メソッドを呼び出して、メッセージを MessageQueue に送信します。 Looper オブジェクトは引き続き、loop() メソッド

を呼び出して、MessageQueue からメッセージを継続的に取り出し、処理のためにハンドラーに渡します。これにより、スレッド間の通信が可能になります。

18. Binder 機構の原理

Android システムの Binder 機構は、Client、Service、ServiceManager、Binder ドライバーで構成されており、Client、Service、Service Manager はそれぞれ実行されます。ユーザー空間では、Binder ドライバーはカーネル空間で実行されます。 Binder は、これら 4 つのコンポーネントを結合する接着剤です。コア コンポーネントは Binder ドライバーです。Service Manager は補助的な管理機能を提供し、Client と Service は Binder ドライバーと Service Manager に基づいています。施設上の C/S 間の通信を実装します。バインダー ドライバーは、ユーザー コントロールと対話するためのデバイス ファイル /dev/binder を提供します。クライアント、サービス、およびサービス マネージャーは、open および ioctl ファイル操作の対応するメソッドを通じてバインダー ドライバーと通信します。クライアントとサービス間のプロセス間通信は、Binder ドライバーを通じて間接的に実装されます。バインダー マネージャーは、サービスを管理し、クライアントにサービス インターフェイスをクエリする機能を提供するデーモン プロセスです。

19. ホット リペアの原理

Java 仮想マシン - JVM はクラスのクラス ファイルをロードし、Android 仮想マシン - Dalvik/ART VM は dex ファイルをロードすることがわかっています。クラスの ,

そして、クラスをロードするときはすべて ClassLoader が必要です。ClassLoader にはサブクラス BaseDexClassLoader があり、BaseDexClassLoader - DexPathList の下に

配列があり、これは dex ファイルを保存するために使用されます。 BaseDexClassLoader のパス findClass メソッドを呼び出すと、実際には配列を走査し、

は対応する dex ファイルを見つけ、見つかった場合はそれを直接返します。ホット リペアの解決策は、新しい dex をコレクションに追加することです。これは古い dex の前にあるため、

それが最初に取り出され、返されます。

20. Android のメモリ リークと管理

(1) メモリ オーバーフロー (OOM) とメモリ リーク (オブジェクトがリサイクルできない) の違い。

(2) メモリ リークの原因

(3) メモリ リーク検出ツール----->LeakCanary

メモリ不足のメモリ オーバーフロー: を参照します。プログラムがメモリを申請しているが、使用するのに十分なメモリ空間がなく、メモリ不足が発生しています。たとえば、整数を申請しているが、long 形式でのみ格納できる数値を格納している場合、それはメモリです。オーバーフロー。平たく言えば、メモリ オーバーフローとは、メモリが不足していることを意味します。

メモリ リーク: メモリ リークとは、プログラムがメモリを申請した後、割り当てられたメモリ領域を解放できないことを意味します。メモリ リークの害は無視できますが、メモリ リークの蓄積による影響は深刻です。いいえメモリがどれだけ多くても、遅かれ早かれ占有されてしまいます Light

メモリ リークの原因:

1. ハンドラーによって引き起こされるメモリ リーク。

解決策: ハンドラーを静的内部クラスとして宣言すると、ハンドラーは外部クラス SecondActivity への参照を保持せず、そのライフサイクルは外部クラスとは何の関係もありません。ハンドラーで必要な場合は、弱い参照を通じて外部クラスを参照できます。

2. シングルトン モードによるメモリ リーク。

解決策: コンテキストは ApplicationContext です。ApplicationContext のライフサイクルはアプリと一致しているため、メモリ リークは発生しません。

3. 静的インスタンスを作成する非静的内部クラスによって発生するメモリ リーク。

解決策: メモリ リークを回避するために内部クラスを静的になるように変更します

4. 非静的匿名内部クラスによってメモリ リークが発生します。

解決策: 匿名内部クラスを静的に設定します。

5. 登録/登録解除の不対使用によるメモリ リーク。

ブロードキャスト レシーバー、EventBus などを登録し、必ずバインドを解除してください。

6. リソース オブジェクトが閉じられていないことが原因でメモリ リークが発生しました。

これらのリソースが使用されていない場合は、close()、destroy()、recycler()、release() などの対応するメソッドを忘れずに呼び出してリソースを解放してください。

7. コレクション オブジェクトを時間内にクリーンアップできなかったために発生するメモリ リーク。

通常、一部のオブジェクトはコレクションに読み込まれます。使用しないときは、関連オブジェクトが参照されないよう、時間内にコレクションを忘れずにクリーンアップする必要があります。

21. フラグメントがフラグメントおよびアクティビティと通信する方法

1. 1 つのフラグメント内の別のフラグメントのメソッドを直接呼び出す

2. インターフェイス コールバックを使用する

3. ブロードキャストを使用する

4.Fragment はアクティビティの public メソッドを直接呼び出します

22. Android UI の適応

フォント match_parent、wrap_content に sp、dp などを使用します。 、weight

画像リソース、対応するフォルダーに配置すると、さまざまな画像の解像度をパーセンテージで置き換えることができます。

23. アプリの最適化

アプリの最適化: (ツール: Hierarchy Viewer 分析レイアウト ツール: TraceView テスト分析に時間がかかります)

アプリの起動の最適化

レイアウトの最適化

レスポンスの最適化

メモリの最適化

バッテリー使用量の最適化

ネットワークの最適化

アプリ起動の最適化(コールドスタート用)

アプリを起動するには 3 つの方法があります:

コールド スタート: アプリが開始されていないか、アプリ プロセスが強制終了されました。アプリ プロセスはシステムに存在しません。アプリの起動この時点ではコールドスタートです。

ホット スタート: ホット スタートとは、アプリ プロセスがバックグラウンドのみにあり、システムがそれをバックグラウンドからフォアグラウンドに移動してユーザーに表示するだけであることを意味します。

コールド スタートとウォーム スタートの間は、通常、次の 2 つの状況で発生します:

(1) ユーザーがアプリを終了し、再度起動します。アプリのプロセスがまだ実行されている可能性があります。ただし、アクティビティを再構築する必要があります。

(2) ユーザーがアプリを終了した後、システムはメモリ上の理由によりアプリを強制終了する可能性があり、プロセスとアクティビティの両方を再起動する必要があります。ただし、パッシブ Kill ロックの保存されたインスタンスの状態は、 onCreate で復元されます。

最適化:

アプリケーションの onCreate (特にサードパーティ SDK の初期化) と最初の画面アクティビティのレンダリングでは、時間のかかる操作を実行する必要はありません。

レイアウトの最適化

ネストが複雑になりすぎないように注意してください。 dcf91641426a34cf32ecc36140f28baf、76deed1c218ccc4d4a17740bf4fefa6a、e7ce6ff74a06bd752b5697fed60b5487

応答の最適化

Android システムは、インターフェイス (アクティビティ) を再描画するために 16 ミリ秒ごとに VSYNC 信号を送信します。

ページラグの原因:

(1)過度に複雑なレイアウト。

(2)UIスレッドの複雑な操作

(3)頻繁に発生するGC が頻繁に発生する 2 つの理由: 1. メモリ ジッター、つまり、短期間に大量のオブジェクトが作成され、すぐに解放される 2. 瞬時に大量のオブジェクトが生成されると、メモリ領域が大幅に占有されます。

メモリの最適化: メモリ リークとメモリ オーバーフローのセクションを参照してください。

バッテリ使用量の最適化 (使用ツール: Batterystats とバグレポート)

(1) ネットワーク リクエストの最適化

(2) 測位に GPS を使用する場合は、忘れずにオフにしてください。

ネットワーク最適化 (ネットワーク接続がユーザーに与える影響: トラフィック、電力、ユーザーの待機) は、次のツール ネットワーク モニターで検出できます。 Android Studio で logcat に

API 設計: アプリとサーバーの間の API 設計では、アプリがビジネス要件とインターフェイス表示を少ない時間で完了できるように、ネットワーク リクエストの頻度、リソースのステータスなどを考慮する必要があります。

Gzip 圧縮: Gzip を使用してリクエストとレスポンスを圧縮し、送信されるデータ量を減らし、トラフィック消費を削減します。

画像のサイズ: サーバーに幅とサイズを伝えることができます。サーバーが無駄を避けるために適切な画像を提供できるように、画像を取得するときに必要な画像の高さを指定します。

ネットワーク キャッシュ: 適切なキャッシュにより、アプリケーションの見た目が高速になるだけでなく、不必要なトラフィックの消費も回避できます。

24. 画像の最適化

(1) 画像自体を操作します。 setImageBitmap、setImageResource、BitmapFactory.decodeResource を使用して大きな画像を設定しないようにしてください。デコードが完了した後、これらのメソッド

は最終的に Java 層の createBitmap を通じて完了され、より多くのメモリが必要となるためです。

(2) 画像の拡大縮小率 SDK では指数値 2 を推奨しています。値が大きいほど画像が不鮮明になります。

(3) 未使用の画像の recycle() メソッドを忘れずに呼び出してください

25. HybridApp WebView と JS の間の対話

Android と JS は、WebView を通じて互いのメソッドを呼び出します。実際、はい:

Android は JS コードを呼び出します

1. WebView のloadUrl() を使用すると、この方法はより簡単で便利です。ただし、効率は比較的低く、戻り値を得るのは困難です。

2. WebView の EvaluateJavascript() を使用すると、このメソッドは非常に効率的ですが、4.4 より上のバージョンでのみサポートされ、4.4 より前のバージョンではサポートされません。したがって、両方を混合して使用することをお勧めします。

JS は Android コードを呼び出します

1. WebView の addJavascriptInterface() を通じてオブジェクト マッピングを実行します。このメソッドは使い方が簡単です。Android オブジェクトと JS オブジェクトをマッピングするだけですが、比較的大きな問題があります.抜け穴。

この脆弱性の理由は、JS が Android オブジェクトを取得すると、システム クラス (java.lang.Runtime クラス) を含む Android オブジェクト内のすべてのメソッドを呼び出して、任意のコードを実行できるためです。

解決策:

(1) Google は、Android 4.2 で、脆弱性攻撃を回避するために、呼び出される関数に @JavascriptInterface の注釈を付けることを規定しています。

(2) Android 4.2 バージョンより前の脆弱性は、intercept prompt() を使用して修正してください。

2. WebViewClient の shouldOverrideUrlLoading () メソッド コールバックを通じて URL をインターセプトします。この方法の利点: 方法 1 の抜け穴がない; 欠点: Android メソッドの戻り値を取得する JS が複雑である。 (iOS では主にこのメソッドが使用されます)

(1)Android は WebViewClient のコールバック メソッド shouldOverrideUrlLoading() を通じて URL をインターセプトします

(2)URL を解析するためのプロトコル

( 3) 事前に合意されたプロトコルが検出された場合は、対応するメソッド

3を呼び出します。onJsAlert()、onJsconfirm()、onJsPrompt()メソッドを通じてJSダイアログボックスalert()、confirm()をインターセプトします。 WebChromeClient のコールバック)、prompt() メッセージ

このメソッドの利点: メソッド 1 に抜け穴がない; 欠点: Android メソッドの戻り値を取得する JS が複雑である。

26. JAVA GC 原則

ガベージ コレクション アルゴリズムの中心的な考え方は、仮想マシンの利用可能なメモリ領域、つまりヒープ領域内のオブジェクトを識別することです。オブジェクトが参照されている場合、それは生きたオブジェクト

と呼ばれます。逆に、オブジェクトが参照されなくなった場合、それはガベージ オブジェクトであり、そのオブジェクトが占有しているスペースは再割り当てのために再利用できます。 。ガベージ コレクション アルゴリズムの選択とガベージ コレクション システム パラメータの適切な調整は、システムのパフォーマンスに直接影響します。

27, ANR

ANR の正式名は Application Not Responding、つまり「アプリケーションが応答しない」です。一定期間内にシステムが操作を処理できない場合、ANR はダイアログ ボックス.

原因:

(1)ユーザー入力イベント (キーボード入力、タッチ スクリーンなど) に応答できません。 5 秒以内。

(2)BroadcastReceiver in 10s 20 秒以内に終了できない

(3) サービスは 20 秒以内に終了できない (可能性が低い)

解決策:

(1) 時間のかかる操作はメインスレッドで実行せず、子スレッドで実装する必要があります。たとえば、onCreate() と onResume() では、作成操作をできるだけ少なくします。

(2) アプリケーションは、BroadcastReceiver で時間のかかる操作や計算を行うことを避ける必要があります。

(3) インテント レシーバーでアクティビティを開始しないでください。新しい画面が作成され、ユーザーが現在実行しているプログラムからフォーカスが奪われてしまいます。

(4)サービスはメインスレッドで実行されるため、サービス内の時間のかかる操作は子スレッドに配置する必要があります。

28. デザインパターン

ここでの拡張:Double Checkの記述が必要です。

シングルケースモード: 悪人スタイルと怠け者スタイルに分割

悪人スタイル:

public class Singleton 
{ 
    private static Singleton instance = new Singleton(); 
     
    public static Singleton getInstance() 
    { 
        return instance ; 
    } 
}

怠け者スタイル:

public class Singleton02 
{ 
    private static Singleton02 instance; 
 
    public static Singleton02 getInstance() 
    { 
        if (instance == null) 
        { 
            synchronized (Singleton02.class) 
            { 
                if (instance == null) 
                { 
                    instance = new Singleton02(); 
                } 
            } 
        } 
        return instance; 
    } 
}

29, RxJava

30、MVP、MVC、MVVM

ここでの拡張子: 手書きの mvp の例、mvc との違い、mvp

MVP モードの利点、モデルに対応- ビジネス ロジックとエンティティ モデル、ビュー - アクティビティに対応し、ビューの描画とユーザーとの対話を担当します、プレゼンター - ビューとモデル間の対話を担当します。MVP モードは MVC モードに基づいています。 Model と View を完全に分離することで、プロジェクトの結合度がさらに低くなる MVC では、プロジェクト内のアクティビティは MVC の C-Controller に相当し、プロジェクト内の論理的な処理はこの C で処理されます。同時に、ビューとモデル間の対話も、mvc におけるすべての論理対話とユーザー対話がコントローラー、つまりアクティビティに配置されると言われています。ビューとモデルは直接通信できます。 MVP モデルはより完全に分離されており、分業が明確になっています。モデル (ビジネス ロジックとエンティティ モデル、ビュー) はユーザーとの対話を担当し、プレゼンターはビューとモデル間の対話を完了する責任を負います。MVP の最大の違いは、 MVC は、MVC でモデルとビューの対話を許可するものであり、MVP では、モデルとビューの間の対話がプレゼンターによって完了することは明らかです。もう 1 つのポイントは、Presenter と View の間の対話がインターフェイス

を介して行われることです。

31. 手書きアルゴリズム (バブリングの選択方法を知っておく必要があります)

32. JNI

(1 ) Cygwin のインストールとダウンロード、Android NDK のダウンロード

(2)ndk プロジェクトでの JNI インターフェースの設計

(3)C/C を使用してローカル メソッドを実装

(4) JNI はダイナミック リンク ライブラリ .so ファイルを生成します

(5) ダイナミック リンク ライブラリを Java プロジェクトにコピーし、Java プロジェクト内で呼び出して、Java プロジェクトを実行します

33. RecyclerView とListView の違い

RecyclerView は ListView と GridView の効果を完成させることができ、さらにウォーターフォール フローの効果も完成させることができます。同時に、リストのスクロール方向 (垂直または水平) を設定することもできます。

RecyclerView でビューを再利用するには、開発者自身がコードを記述する必要はなく、システムがすでにパッケージ化されています。 。

###RecyclerView は部分的な更新を実行できます。 ###

RecyclerView はアイテムのアニメーション効果を実現する API を提供します。

パフォーマンスの観点:

データを頻繁に更新し、アニメーションを追加する必要がある場合は、RecyclerView の方が大きな利点があります。

リストとして表示されるだけであれば、両者の差はそれほど大きくありません。

34. Universal-ImageLoader、Picasso、Fresco、Glide の比較

Fresco は Facebook が立ち上げたオープンソースの画像キャッシュ ツールで、主な機能は次のとおりです: 2 つのメモリ キャッシュとネイティブ キャッシュの構成3 レベルのキャッシュ、

利点:

1. イメージは、仮想マシンのヒープ メモリではなく、Android システムの匿名共有メモリに保存されます。画像のデータもローカル ヒープ メモリに保存されるため、アプリケーションはより多くのメモリを使用し、画像の読み込みによる OOM が発生せず、ビットマップをリサイクルするためのガベージ コレクターの頻繁な呼び出しによって引き起こされるインターフェイスの遅延も軽減されます。より高いパフォーマンス。

2. JPEG 画像のプログレッシブ読み込み。ぼやけた画像から鮮明な画像までの読み込みをサポートします。

3. 画像は、画像の中心だけでなく、任意の中心点に ImageView に表示できます。

4. JPEG 画像のサイズ変更も、仮想マシンのヒープ メモリではなくネイティブで行われるため、OOM も削減されます。

5. GIF 画像の表示に対する非常に優れたサポート。

欠点:

1. フレームワークが大きいため、APK サイズに影響します

2.

Universal-ImageLoader を使用するのが面倒です: ( HttpClient は Google に置き換えられると推定されています (諦めると、作者はこのフレームワークの維持を諦めることになります)

利点:

1. ダウンロードの進行状況の監視をサポート

2ビューのスクロール中に画像の読み込みを一時停止するには、PauseOnScrollListener インターフェイスを使用します。 ビューのスクロール中に画像の読み込みを一時停止します。

3. さまざまなメモリ キャッシュ アルゴリズムがデフォルトで実装されています。これらのイメージ キャッシュはすべて、キャッシュ アルゴリズムを使用して構成できます。ただし、ImageLoader は、最大サイズから順、使用頻度の低いものから順に削除など、多くのキャッシュ アルゴリズムをデフォルトで実装しています。最も最近使用されていないもの、先入れ先出し、最長入れ先出しなど。

4. ローカルキャッシュファイル名ルール定義をサポート

Picasso の利点

1. 統計監視機能付き。キャッシュ ヒット率、使用済みメモリ サイズ、保存されたトラフィックなどを含む、画像キャッシュの使用状況の監視をサポートします。

2. 優先処理をサポートします。各タスクをスケジュールする前に、優先度の高いタスクが選択されます。たとえば、アプリ ページのバナーの優先度がアイコンの優先度よりも高い場合に適しています。

3. 画像サイズの計算が完了して読み込みが完了するまでの遅延をサポートします。

4. フライト モードをサポートします。同時スレッドの数はネットワークの種類に応じて変化します。電話機が機内モードに切り替わったり、ネットワークの種類が変更されたりすると、スレッド プールの最大同時実行数が自動的に調整されます。たとえば、Wi-Fi の最大同時実行数は 4、4g は 3、3g は 2 になります。ここで Picasso は、CPU コアの数ではなく、ネットワーク タイプに基づいて同時実行の最大数を決定します。

5. ローカル キャッシュは「なし」です。 「No」ローカルキャッシュはローカルキャッシュがないという意味ではなく、Picasso自身は実装しておらず、Squareの別のネットワークライブラリであるokhttpに渡して実装させています。応答ヘッダーで Cache-Control と Expired をリクエストすることによって有効期限を設定します。 有効期限

Glide の利点

1. 画像だけでなくメディア ファイルもキャッシュできます。Glide は画像だけではありませんキャッシュ、Gif、WebP、サムネイルをサポートします。ビデオもサポートするため、メディア キャッシュとして使用する必要があります。

2. 優先処理をサポートします。

3. アクティビティ/フラグメントの寿命と一致します。サイクル、trimMemory をサポートします。Glide は、FragmentTransaction を介して各コンテキストの RequestManager を維持します。これは、Activity/Fragment ライフ サイクルとの一貫性を維持し、呼び出しに使用できる対応する TrimMemory インターフェイス実装があります。

4. okhttp とVolley. Glide はデフォルトで UrlConnection を通じてデータを取得し、okhttp または Volley で使用できます。実際、ImageLoader と Picasso も okhttp と Volley をサポートしています。

5. メモリに優しい Glide のメモリ キャッシュはアクティブな設計になっています。メモリキャッシュからデータを取得する際には、一般的な実装のようにgetを使用するのではなく、removeを使用し、このキャッシュされたデータを値がソフト参照であるactiveResourcesマップに入れて、参照数をカウントします。参照カウントが空の場合は再利用する メモリキャッシュの小さい画像、Glide url、view_width、view_height、画面解像度などを結合キーとして、処理後の画像をメモリキャッシュにキャッシュサイズを節約するために元の画像の代わりに使用されます。アクティビティ/フラグメントのライフサイクルと一致しており、トリムメモリをサポートしています。デフォルトの画像がデフォルトで使用されます。ARGB_888 の代わりに RGB_565 が使用されます。定義は悪くなりますが、画像は小さくなり、 ARGB_888.

に設定されています。 6.Glide は、署名を通じて、またはローカル キャッシュを使用せずに URL の有効期限をサポートできます。

42. Xutils、OKhttp、Volley、Retrofit の比較

Xutils は、ネットワーク リクエスト、画像の読み込み、データ ストレージ、ビューの注釈付けを実行できる非常に包括的なフレームワークです。このフレームワークを使用すると非常に便利ですが、欠点もあります。また、このプロジェクトを使用すると、プロジェクトが非常に依存することになることは明らかです。このフレームワークに問題が発生すると、プロジェクトに大きな影響を及ぼします。 ,

OKhttp: Android 開発では、既製の API を直接使用してネットワーク リクエストを行うことができます。操作には HttpClient と HttpUrlConnection を使用するだけです。 Java および Android プログラムの場合、okhttp は、同期と非同期をサポートする高性能の http リクエスト ライブラリをカプセル化します。さらに、okhttp は、スレッド プール、データ変換、パラメータの使用法、エラー処理などもカプセル化します。 APIを使うとさらに便利になります。ただし、プロジェクトで使用する場合は、よりスムーズに使用できるように、カプセル化のレイヤーを自分で作成する必要があります。

Volley: Volley は、Google によって正式にリリースされた、小規模で優れた非同期リクエスト ライブラリのセットです。このフレームワークは拡張性が高く、HttpClient、HttpUrlConnection、さらには OkHttp をサポートしており、Volley は ImageLoader もカプセル化します。画像読み込みフレームワークを使用する必要さえありません。ただし、この機能は、一部の特殊な画像読み込みフレームワークほど強力ではありません。単純なニーズには使用できますが、より複雑な要件には依然として特殊な画像読み込みフレームワークの使用が必要です。 。 Volleyにはポストビッグデータをサポートしていないなどの欠点もあり、ファイルのアップロードには適していません。ただし、Volley の設計自体の本来の目的は、少量のデータ量で頻繁にネットワーク要求を行うことです。

Retrofit: Retrofit は、Square によって作成された、デフォルトで OkHttp カプセル化に基づく RESTful ネットワーク リクエスト フレームワークです。RESTful は、現在一般的な API 設計スタイルであり、標準ではありません。 Retrofit のカプセル化は非常に強力であると言えます。これには一連の設計パターンが含まれます。リクエストはアノテーションを通じて直接設定できます。さまざまな http クライアントを使用できます。デフォルトでは http が使用されますが、さまざまな Json コンバータを使用してデータをシリアル化できます。同時に、RxJava のサポートを提供するには、Retrofit OkHttp RxJava Dagger2 を使用してください。現在、比較的流行しているフレームワークと言えますが、比較的高い敷居が必要です。

Volley VS OkHttp

Volley の利点は、カプセル化が優れていることですが、OkHttp を使用するには、再度カプセル化するのに十分な能力が必要です。 OkHttp の利点はパフォーマンスの高さであり、OkHttp は NIO とokio をベースにしているため、Volley よりもパフォーマンスが高速です。 IO と NIO は両方とも Java の概念です。ハードディスクからデータを読み取る場合、最初の方法は、プログラムがデータが読み取られるまで待ってから続行するというものです。これは最も単純で、ブロッキング IO とも呼ばれます。1 つの方法は、データを読み取ると、プログラムは実行を継続し、データが処理された後に通知して、コールバックを処理します。 2 番目の方法は NIO で、ノンブロッキングなので、もちろん NIO の方が IO よりもパフォーマンスが優れています。Okio は IO と NIO に基づいて Square によって作成されたライブラリであり、データ ストリームの処理がよりシンプルで効率的です。理論的には、Volley と OkHttp を比較すると、Volley を使用する傾向が高くなります。Volley は内部的に OkHttp の使用もサポートしているため、OkHttp のパフォーマンス上の利点はなくなり、Volley 自体は使いやすくパッケージ化されており、スケーラビリティが優れています。

OkHttp VS Retrofit

Retrofit がデフォルトで OkHttp に基づいたパッケージであることは疑いの余地がありませんが、この点に関しては比較対象がなく、間違いなく Retrofit が優先されます。

Volley VS Retrofit

両方のライブラリは適切にカプセル化されていますが、Retrofit はより完全に分離されており、特に Retrofit 2.0 がリリースされると、Jake は以前の 1.0 設計の不合理な部分を修正します。 , 責任はさらに細分化されており、Retrofit はデフォルトで OkHttp を使用するため、パフォーマンスの点で Volley よりも優れています。さらに、プロジェクトで RxJava を使用している場合は、Retrofit を使用する必要があります。したがって、これら 2 つのライブラリと比較すると、Retrofit の方が優れているため、両方のフレームワークを使いこなすことができる場合は、まず Retrofit を使用することをお勧めします。ただし、Retrofit は Volley に比べて若干敷居が高く、その原理やさまざまな用途を完全に理解するにはある程度の労力が必要ですので、少しだけ知っている場合は商用プロジェクトで Volley を使用することをお勧めします。

Java

1. スレッドにおけるスリープと待機の違い

(1) これら 2 つのメソッドは異なるクラスから来ており、スリープはスレッドから来ており、待機はオブジェクトから来ています。 ;

(2) sleep メソッドはロックを解放しませんが、wait メソッドはロックを解放します。

(3)wait、notify、notifyAll は同期制御メソッドまたは同期制御ブロックでのみ使用できますが、sleep はどこでも使用できます。

2. Thread の start() メソッドと run() メソッドの違いは何ですか?

start() メソッドは、新しく作成されたスレッドを開始するために使用され、内部的に start() が実行されます。 run() ) メソッドを呼び出しますが、 run() メソッドを直接呼び出すのとは異なります。 run() メソッドを直接呼び出す場合は、通常のメソッドと変わりません。

3. キーワード「final」と「static」の使用方法。


final:

1.final 変数は定数であり、値を割り当てることができるのは 1 回だけです。

2. 最終メソッドはサブクラスによってオーバーライドできません。

3. 最終クラスは継承できません。

static:

1. 静的変数: メモリ内には静的変数のコピーが 1 つだけあります (メモリの節約)。JVM は静的変数にメモリを 1 回だけ割り当てます。クラスロード後 静的変数のメモリ確保はプロセス内で完了し、クラス名で直接アクセスできる(便利) もちろんオブジェクト経由でアクセスすることも可能(ただし非推奨)。

2. 静的コード ブロック

静的コード ブロックは、クラスのロード時の初期化中に自動的に実行されます。

3. 静的メソッド

静的メソッドはクラス名を介して直接呼び出すことができ、任意のインスタンスを呼び出すこともできるため、静的メソッド内で this および super キーワードを使用することはできません.

所属するクラスのインスタンス変数やインスタンス メソッド (つまり、静的でないメンバー変数やメンバー メソッド) に直接アクセスすることはできません。アクセスできるのは、所属するクラスの静的なメンバー変数やメンバー メソッドのみです。

4. String、StringBuffer、StringBuilder の違い

1. 3 つの実行速度: StringBuilder > StringBuffer > String (String は定数で変更できないため、スプライシング中に再作成されます。新しいオブジェクト)。

2. StringBuffer はスレッドセーフですが、StringBuilder はスレッドアンセーフです。 (StringBuffer にはバッファがあるため)

5. Java でのオーバーロードと書き換えの違い:

1. オーバーロード: クラス内に同じ名前のメソッドが複数存在する可能性がありますが、パラメーターは種類も数も違います。これは過負荷です。

2. 書き換え: サブクラスが親クラスを継承する場合、サブクラスは親クラスのメソッドを実装できるため、新しいメソッドが親クラスの古いメソッドを上書きします。

6. HTTP https コストの違い。

2. http はハイパーテキスト転送プロトコルであり、情報は平文で送信されますが、https は安全な SSL 暗号化送信プロトコルです。

3. http と https はまったく異なる接続方法を使用し、使用するポートも異なります。前者は 80、後者は 443 です。

4. http 接続は非常にシンプルでステートレスです。HTTPS プロトコルは、SSL HTTP プロトコルから構築されたネットワーク プロトコルで、暗号化された送信と ID 認証を実行でき、http プロトコルよりも安全です。

https 実装原則:

(1) お客様は https の URL を使用して Web サーバーにアクセスし、Web サーバーとの SSL 接続を確立する必要があります。

(2) クライアントのリクエストを受信した後、Web サーバーは Web サイトの証明書情報 (証明書には公開キーが含まれています) のコピーをクライアントに送信します。

(3) クライアントのブラウザと Web サーバーは、SSL 接続のセキュリティ レベル (情報暗号化のレベル) のネゴシエーションを開始します。

(4) クライアントのブラウザは、双方が合意したセキュリティ レベルに基づいてセッション キーを確立し、Web サイトの公開キーを使用してセッション キーを暗号化し、Web サイトに送信します。

(5) Web サーバーは、独自の秘密キーを使用してセッション キーを復号化します。

(6) Web サーバーはセッション キーを使用してクライアントとの通信を暗号化します。

7. HTTP は TCP/IP モデルのどの層に位置しますか? HTTP が信頼できるデータ転送プロトコルであるのはなぜですか?

Tcp/ip 5 層モデル:

下から上へ: 物理層 -> データリンク層 -> ネットワーク層 -> トランスポート層 -> アプリケーション層

このうち、tcp/ip はモデル内のネットワーク層に位置し、ICMP (Network Control Message Protocol) も同じ層にあります。 http はモデルのアプリケーション層にあります

tcp/ip は信頼性の高い接続指向プロトコルであり、http はトランスポート層の tcp/ip プロトコルに基づいているため、http は信頼性の高いデータ送信です。プロトコル。

8. HTTP リンクの特性

HTTP 接続の最も重要な特徴は、クライアントが送信した各リクエストに対してサーバーが応答を返す必要があることです。リクエストが完了すると、接続は確立されません。積極的にリリースしていきます。

コネクションを確立してからコネクションを閉じるまでの処理を「コネクション」と呼びます。

9. TCP と UDP

tcp の違いは接続指向であり、tcp 接続では 3 回のハンドシェイクが必要なため、リスクを最小限に抑え、接続の信頼性を確保できます。

udp は接続指向ではありません。UDP は接続を確立する前にオブジェクトとの接続を確立する必要はありません。送信中も受信中も確認信号は送信されません。したがって、udp は信頼できません。

UDP は接続を確認する必要がないため、オーバーヘッドが少なく、転送速度が高く、リアルタイム性が優れています。

10. Socket がネットワーク接続を確立する手順

Socket 接続を確立するには、少なくとも 1 組のソケットが必要で、そのうちの 1 つはクライアント (ClientSocket) で実行され、もう 1 つはクライアント (ClientSocket) で実行されます。サーバー--ServiceSocket

1. サーバー監視: サーバー側ソケットは特定のクライアント ソケットを見つけませんが、接続を待機し、ネットワーク ステータスをリアルタイムで監視し、接続を待機している状態です。クライアントの接続リクエスト。

2. クライアント要求: 接続要求を行うクライアントのソケットを指し、接続対象はサーバーのソケットです。注: クライアントのソケットは、接続先のサーバーのソケットを記述する必要があります。

はサーバー ソケットのアドレスとポート番号を示し、サーバー側ソケットと同様に接続要求を行います。

3. 接続確認: サーバー側ソケットはクライアント ソケットの接続要求を監視すると、クライアント ソケットの要求に応答して新しいスレッドを確立し、サーバー側ソケットを

という単語の説明がクライアントに送信され、クライアントがこの説明を確認すると、両者は正式に接続を確立します。サーバー ソケットは引き続きリッスン状態にあり、他のクライアント ソケットからの接続要求を受信し続けます。

11. Tcp/IP の 3 方向ハンドシェイクと 4 方向ウェーブ

以上が中級および上級の Android 面接の質問 (回答付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。