ホームページ > 記事 > ウェブフロントエンド > Alibaba およびその他の主要メーカーへのインタビューで Android 開発者が遭遇した問題をまとめたもの
おすすめ記事: 「2020 Android 面接質問まとめ【まとめ】」
私の過去 4 年間について簡単にお話しさせていただきます。経験。 「たくさんの企業と面接をしましたが、興奮した企業もあれば、残念で無力な気持ちになった企業もあり、そのすべてを記録しました。よく考えてみると、それだけの価値があったのです。たくさんの企業を面接した結果、何もなければ、結局のところ、残るのはとてももったいないです。少なくとも私にとっては、整理してまとめてみないと明確な答えが出ないこともあります。これから転職を考えている方、または転職を考えている方の参考になれば幸いです。
以下の質問に対する答えは、私が過去 4 年間に取材してまとめたものですので、異なる意見がございましたら、遠慮なくご指摘ください。
回答:
一般に、非静的内部クラスがハンドラーへの参照を保持する場合、 external class が原因で、使用後にシステムが外部クラスを再利用できなくなり、メモリ リークが発生します。この問題を回避するには、カスタマイズしたハンドラーを静的内部クラスとして宣言し、ハンドラーに弱参照を通じて外部クラスへの参照を保持させ、メモリ リークを回避します。
以下はコードの実装です
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private TextView mTextView; private WeakReference<MainActivity> activityWeakReference; private MyHandler myHandler; static class MyHandler extends Handler { private MainActivity activity; MyHandler(WeakReference<MainActivity> ref) { this.activity = ref.get(); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: //需要做判空操作 if (activity != null) { activity.mTextView.setText("new Value"); } break; default: Log.i(TAG, "handleMessage: default "); break; } } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //在onCreate中初始化 activityWeakReference = new WeakReference<MainActivity>(this); myHandler = new MyHandler(activityWeakReference); myHandler.sendEmptyMessage(1); mTextView = (TextView) findViewById(R.id.tv_test); } }复制代码
参考ブログ投稿 blog.csdn.net/ucxiii/arti…
分析:
Android アプリケーションを開発する場合、あるアクティビティから別のアクティビティを開始して、新しいアクティビティにデータを渡すのは非常に簡単ですが、アクティビティを実行させる必要がある場合は、バックグラウンドでの戻り フロントデスクに行ってデータを渡す際に、若干の問題が発生する可能性があります。
まず、デフォルトでは、インテントを通じてアクティビティを開始すると、同じ実行中のアクティビティがすでに存在する場合でも、システムは新しいアクティビティ インスタンスを作成して表示します。アクティビティが複数回インスタンス化されないようにするには、AndroidManifest でアクティビティの読み込みモード (launchMode) を設定する必要があります。アクティビティに対して、システムがすでにインスタンスを持っている場合、システムはこのインスタンスにリクエストを送信します。ただし、この時点では、システムは通常リクエスト データを処理する onCreate メソッドを呼び出すのではなく、onNewIntent メソッドを呼び出します
回答:前提: ActivityA は開始されており、現在のアプリケーションのアクティビティ スタック内にあります。 ActivityA の LaunchMode が SingleTop の場合、ActivityA がスタックの最上位にあり、ActivityA を再度開始したい場合は、onNewIntent() メソッドが呼び出されます。 ActivityA の LaunchMode が SingleInstance、SingleTask の場合、ActivityA がすでにスタック内にある場合は、この時点で onNewIntent() メソッドが呼び出されます。
ActivityA の LaunchMode が Standard の場合、ActivityA が開始されるたびに、新しいインスタンスは元の起動とは何の関係もないので、元の ActivityA の onNewIntent メソッドは呼び出されません。onCreate メソッドは引き続き呼び出されます。
次はコード例です
#1. MainActivity の起動を設定します。モードは SingleTask (スタック内で再利用)です。
6b4b8de82f5ec1f2a7986e15ef3b7143 abedf4926b16e78349669730db0843a2复制代码2. MainActivity の onNewIntent メソッドをオーバーライドします。
<activity android:name=".MainActivity"android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>复制代码3.Main2Actvity は click Jump を実行し、MainActivity は再利用され、onNewIntent メソッドが実行されます。
package code.xzy.com.handlerdemo; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private Button mButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton = (Button) findViewById(R.id.forward_btn); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(MainActivity.this, Main2Activity.class)); } }); } @Override protected void onNewIntent(Intent intent) { Toast.makeText(this, "onnewIntent", Toast.LENGTH_SHORT).show(); Log.i(TAG, "onNewIntent: i done...."); } }复制代码スクリーンショットを印刷**体系的な高レベル アーキテクチャのビデオの完全なセットをここに示します。 **7 つの主流テクノロジー モジュール、ビデオ ソース コード 注 (
詳細なインタビュー資料をまとめた特別パッケージが記事の最後にあります。
)3. の利点は何ですか? RecyclerView と ListView の比較
まず、RecyclerView の名前について説明します。クラス名から判断すると、RecyclerView の意味は、 Recycler View のみを考慮します。つまり、RecyclerView はビューのみをリサイクルして再利用します。その他は自分で設定できます。高度な分離により、完全なカスタマイズの自由が得られることがわかります (したがって、このコントロールを通じて ListView、GirdView、ウォーターフォール フロー、その他の効果を簡単に実現できます)
第 2 に、RecyclerView は、次の機能を追加および追加する機能を提供します。項目の削除、アニメーション効果、カスタマイズ可能ListView と比較した RecyclerView の利点は、次のことを簡単に実現できることです。ListView の機能
参考
jcodecraeer.com/a/anzhuokai… blog.csdn.net/lmj62356579… www.360doc.com/content/16/…
回答:
Proguard テクノロジー次の機能があります:
圧縮 -- コード内の不要なクラスをチェックして削除します。 最適化 -- バイトコードを最適化し、不要なバイトコードを削除します。 難読化 - 逆コンパイルを避けるために定義の名前を難読化します。
事前監視 -- Java プラットフォームで処理されたコードを再度検出します
コードの難読化は、オンラインになるときのみ使用され、デバッグされます。モードではオフになり、オプションのテクノロジです。
それでは、なぜコード難読化を使用するのでしょうか?
Java はクロスプラットフォームで解釈される開発言語であり、Java のソース コードはバイトにコンパイルされてコード ファイルが保存されるためです。クロスプラットフォームのニーズにより、Java バイトコードには変数名、メソッド名などの多くのソース コード情報が含まれています。これらの名前を通じて変数やメソッドにアクセスします。これらの変数の多くは意味がありませんが、Java ソース コードに簡単に逆コンパイルできます。この現象を防ぐには、プロガードを使用して Java バイトコードを難読化する必要があります。難読化とは、再編成し、公開したプログラムを加工して、前処理したコードと機能が同じでコード表示が異なるコードを逆コンパイルしても、コードの意味やどの部分が難読化されているかが分かりにくくなります。前のロジックに従って実行され、同じ結果が得られます。
ただし、一部の Java クラスは混同できません。たとえば、シリアル化を実装する Java クラスを混同しないと、逆シリアル化中に問題が発生します。
次のコードを難読化する場合は、難読化せずに保持するように注意する必要があります。
android.app.backup.BackupAgentHelper
android.preference など、その他の Anroid 公式推奨事項は混乱を招くものではありません。 . Preference7. Android アクティビティの内部メカニズムを簡単に説明します
##8. Give a Android フレームワーク層の特定のモジュール (またはシステム アプリ) の簡単な紹介 9. Android ハンドラーのメカニズムと原理10. スレッド間通信とプロセス間通信の違いは何ですか?また、Android 開発プロセスでどのように実装されるかwww .cnblogs.com/yangtao1995…
11. プロジェクトのメモリ最適化の詳細をいくつか簡単に説明します
回答:私の個人的な理解では、Android ビューのレンダリングは、測定、レイアウト、描画の 3 つのステップを経る必要があると考えています。測定プロセスはツリー構造で継続的に実行されます。UI レベルが深くネストされている場合は、必ず時間がかかります。多くの時間がかかるため、ネストのレベルを下げ、ツリー構造がフラットであることを確認し、レンダリングする必要のないビューを削除するようにしてください。
カスタム ビューの手順:
Android カスタム ビューの一般的な手順
Volley チュートリアル blog.csdn.net/ jdfkldjlkjd…
TCP と UDP の基本的な違い
データグラム指向の方法
アダプター モード: インターフェースを顧客が望む別のインターフェースに変換します。アダプター モードを使用すると、互換性のないインターフェースを持つクラスを連携させることができます。別名はラッパー (Wrapper)です。
装飾モード: 動的に追加します。オブジェクト関数の追加という点では、装飾モードはサブクラス実装を生成するよりも柔軟です。装飾パターンはオブジェクトの構造パターンです。
使用シナリオ:他のオブジェクトに影響を与えることなく、動的かつ透過的な方法で単一のオブジェクトに責任を追加します。
オブジェクトの機能を拡張する場合、装飾モードは継承よりも柔軟であり、急激な増加にはつながりません。クラスの数で。
オブジェクトの機能は、動的な方法で拡張できます。
オブジェクトは、さまざまな特定の装飾クラス、およびこれらの装飾クラスの順列と組み合わせを使用して、複数回装飾できます。
実用的なアプリケーション:
Android での Context クラスの実装
外観モード:主な目的は、外部および内部サブシステム モジュール間の相互作用により、外部からのサブシステムの使用が容易になります。これは、クライアント要求をサブシステム内のさまざまなモジュールに転送して処理する役割を果たします。
使用シーン:**合成モード:**「部分全体」階層を実現するためにオブジェクトをツリー構造に編成し、クライアントが単一オブジェクトと結合オブジェクトを一貫して使用できるようにします。 。 使用シナリオ: 利点: 1. 高レベルのモジュール呼び出しは簡単です
2. ノードを自由に追加します ** テンプレート メソッド: ** は、アルゴリズム スケルトンを通じてサブクラスへのアルゴリズムのステップを遅延させ、サブクラスがこれらのステップの実装をオーバーライドして特定のアルゴリズムを実装できるようにします。 その使用シナリオ: オブザーバー パターン: オブジェクト間の 1 対多の関係を定義します。依存関係により、オブジェクトの状態が変化するたびに、関連する依存オブジェクトが通知され、自動的に更新されます。 使用シナリオ: 特定のアプリケーション: たとえば、コールバック モードでは、抽象クラス/インターフェイスを実装するインスタンスが親クラスによって提供される抽象メソッドを実装した後、そのメソッドが親クラスに返されて、Listview の notifyDataSetChanged を処理します。 RxJava Observer パターンの場合 **責任チェーン モード:**リクエストには処理する複数のオブジェクトがあります。これらのオブジェクトはチェーンですが、どのオブジェクトを処理するかは条件判断に基づいて決定されます。処理できない場合は処理が行われます。オブジェクトが処理するまで、チェーン内の次のオブジェクトに渡されます。 使用シナリオ:1. 同じリクエストを処理できるオブジェクトが複数あり、リクエストを処理する特定のオブジェクトは実行時に決定されます。
2. 受信者を明示的に指定せずに、複数のオブジェクトの 1 つにリクエストを送信します。 実践的な応用:Try...catch ステートメント
注文されたブロードキャスト
モーションイベント:actionDwon actionMove actionUp
イベント配信メカニズムの 3 つの重要なメソッド:dispatchTouchEvent.onInterceptTouchEvent.onTouchEvent **戦略パターン:**一連のアルゴリズムを定義し、それらを 1 つずつカプセル化し、交換可能にします。このパターンでは、アルゴリズムを使用するクライアントとは独立してアルゴリズムを変更できます。ストラテジ パターンの使用シナリオ: クラスはさまざまな動作を定義しており、これらの動作は、このクラスのメソッド内の複数の条件ステートメントの形式で表示されます。その後、ストラテジ パターンを使用して、メソッド内で多数の条件ステートメントを使用することを回避できます。クラス。 使用シナリオ: クラスは複数の動作を定義し、これらの動作はこのクラスのメソッド内の複数の条件ステートメントの形式で表示されます。その後、戦略パターンを使用してロットの使用を回避できます。条件文の。 利点:1.コンテキストと特定の戦略 ConcreateStrategy は疎結合です。
2. 戦略モードはオープンクローズ原則を満たします 特定のアプリケーション: バイト ストリーム操作の基本単位はバイト、文字ストリーム操作の基本単位は Unicode コード要素 (2 バイト) です。
バイト ストリームはデフォルトではバッファを使用しませんが、文字ストリームはバッファを使用します。 バイト ストリームは、通常、バイナリ データの処理に使用されます。実際、あらゆるタイプのデータを処理できますが、Unicode コード要素の直接の書き込みや読み取りはサポートされていません。文字ストリームは通常、テキスト データを処理します。 Unicode コード要素の書き込みと読み取りをサポートします。 Java における文字ストリームとバイトストリームの違いを理解するためのリファレンス Viewおよび ViewGroup 基本的な描画プロセス 1 つだけ この場合、次のことが可能です。try ステートメントで大きなオブジェクトが宣言されて OOM が発生し、OOM が try ステートメントのオブジェクト宣言によって引き起こされていることが確認でき、その後、これらのオブジェクトがcatch ステートメントで解放し、OOM 問題を解決して、残りのステートメントの実行を続行できます。 しかし、これは通常、適切なアプローチではありません。 OOM を明示的にキャッチすることに加えて、SoftReference、WeakReference、ハードディスク キャッシュなど、Java でメモリを管理するより効果的な方法があります。 JVM のメモリが不足する前に GC が複数回トリガーされ、これらの GC によりプログラム操作の効率が低下します。 OOM の原因が try ステートメント内のオブジェクトではない場合 (メモリ リークなど)、OOM は catch ステートメントでスローされ続けます blog.csdn.net/u010652002/… 回答: blog.csdn.net/xmc28114194… 回答: データベースを使用する必要がある場合は、DatabaseManager の openDatabase() メソッドを使用して、この方法ではシングルトン モードを使用し、データベース オブジェクトの一意性、つまりデータベースを操作するたびに使用される SQLite オブジェクトが一貫して取得されるようにします。次に、参照カウントを使用して、データベース オブジェクトを作成するかどうかを決定します。参照カウントが 1 の場合はデータベースを作成する必要があり、1 以外の場合はすでにデータベースが作成されています。
closeDatabase()メソッドでは参照カウントの値も判定しており、参照カウントが0になった場合はデータベースを閉じる必要があります。 一般的なアプローチは、マルチスレッド アクセスの場合、Sqlite データベースの読み取りと書き込みを管理するために、DatabaseManager を自分でカプセル化する必要があるということです。同期が必要、非同期が必要、非同期が必要です。 . 起こりやすいデータベースの直接操作は行わないでください ロックの問題により、ロック後の操作に失敗しました。 この回答は、この記事 blog.csdn.net/rockcode_li... 分析: leetcode 2 つのリンク リストの交点 www.360doc.com/content/16/… 次のアイデアがあります: (1) ブルート フォース クラッキング、すべてのリンク リスト A ノードを走査し、各ノードについてリンク リスト B 内のすべてのノードと比較され、終了条件は B 内の最初の等しいノードを見つけることです。時間計算量は O(lengthA*lengthB)、空間計算量は O(1) です。 (2) ハッシュテーブル。リンク リスト A を走査し、ノードをハッシュ テーブルに保存します。次に、リンク リスト B を走査し、B の各ノードについてハッシュ テーブルを検索します。ハッシュ テーブル内で見つかった場合、それが交差が始まるノードであることを意味します。時間計算量は O(長さ A 長さ B)、空間計算量は O(長さ A) または O(長さ B) です。 (3) ダブル ポインタ メソッド。ポインタ pa と pb は、それぞれリンク リスト A と B の最初のノードを指します。 リンク リスト A を走査し、その長さ lengthA を記録します。リンク リスト B を走査し、その長さ lengthB を記録します。 2 つのリンクされたリストの長さは異なる可能性があるため、たとえば、質問に示されている場合、長さ A=5、長さ B=6、その場合、差は長さ B-長さ A=1 となり、ポインタはpb は連結リスト B の最初のノードから変更され、2 番目のノードを指す 1 歩を開始し、pa は連結リスト A の最初のノードを指し、その後同時に 1 歩進みます。それらは交差ノードです。 現在、Android 開発は以前ほど人気がありませんが、上級人材は依然として不足しています。この文に見覚えはありますか。上級 Web 人材も含まれているため、人材不足、c シニア 人材は依然として不足しているため、人工知能の時代には、高レベルの人材も不足するでしょう。 ハイレベルな人材は他の分野でもハイレベルな人材であり、人気のあるものを選んだからすべてがうまくいくわけではないようです。 上級エンジニアのインタビューに関連する記事がオンライン上に混在しており、内容が多すぎたり、内容の質が低すぎたりします。 これを考慮すると、 Android 開発シニア エンジニアの面接でよく聞かれる質問と回答をまとめましたので、参考にしてください。無事にシニア エンジニアに昇進することができました。現在、大手メーカーでシニア Android エンジニアとして働いています。現在の環境では、私も「Android エンジニアに貢献します。これらの質問は、よく検討して良いと思った上で整理しました。上級エンジニアには、駆け出しのような 1 つや 2 つの文で明確に表現できるような質問はされないことを知っているので、私はこう思います」誰もが理解できるように記事をフィルタリングしましたので、皆様のお役に立てれば幸いです。
16.バイトストリーム 文字ストリームとの違い
17. ビューの描画処理、親ビューを先に計測するか子ビューを先に計測するか
18. OOM 例外は try...catch でキャッチできますか (または、メモリ不足エラーの発生を回避するために try-catch でキャプチャできますか?)
# の違い##Java の StrongReference、SoftReference、WeakReference と PhantomReference の違い
20. 100 ピクセル*100 ピクセルの画像が占有するメモリを計算してください
21.okHttp 実装の原則
22. okHttp にはどのようなインターセプターがありますか?
23. 1 2 を計算してください! 3! 4! 5! ... 20! コードで実装された結果
24. シングルトン モード、どのモードがスレッド セーフであるか、およびなぜスレッド セーフなのかを記述します
25. レトロフィット実装の原則
26.Android 画像の形式は何ですか?
27.sqlite はマルチスレッド操作を実行できますか?マルチスレッド データベース操作のセキュリティ 性別
28 を参照しています。既知の長さを持つ 2 つのリンク リストがあります。2 つのリンク リストの共通部分を決定する方法
終了
以上がAlibaba およびその他の主要メーカーへのインタビューで Android 開発者が遭遇した問題をまとめたものの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。