Empfohlen: „Zusammenfassung der Android-Interviewfragen 2020 [Sammlung] “
Lassen Sie mich kurz über mein Interview der letzten vier Jahre sprechen Erfahrung. Ich habe mit vielen Unternehmen gesprochen, und einige von ihnen haben mich aufgeregt, andere haben mich enttäuscht und hilflos gemacht. Nachdem ich so viele Unternehmen interviewt habe, hat es sich gelohnt Am Ende wäre es eine Verschwendung zu bleiben. Zumindest für mich lassen sich manche Dinge erst nach dem Aussortieren und Zusammenfassen mit einer eindeutigen Antwort beantworten. Ich hoffe, dass dies für Sie von Nutzen sein kann, wenn Sie kurz vor einem Jobwechsel stehen oder planen, nach Möglichkeiten zu suchen.
Die Antworten auf die folgenden Fragen wurden alle durch persönliche Interviewpraxis der letzten vier Jahre zusammengestellt. Wenn Sie anderer Meinung sind, können Sie mich gerne korrigieren.
Antwort:
Im Allgemeinen, wenn eine nicht statische innere Klasse einen Verweis auf einen enthält äußere Klasse Dies führt dazu, dass die externe Klasse nach der Verwendung nicht vom System zurückgefordert werden kann, was zu einem Speicherverlust führt. Um dieses Problem zu vermeiden, können wir den angepassten Handler als statische innere Klasse deklarieren und ihn dann über eine schwache Referenz einen Verweis auf die externe Klasse halten lassen, um so Speicherlecks zu vermeiden.
Das Folgende ist die Code-Implementierung
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); } }复制代码
Siehe den Blogbeitrag blog.csdn.net/ucxiii/arti...
Analyse:
Bei der Entwicklung von Android-Anwendungen ist es sehr einfach, eine andere Aktivität von einer Aktivität aus zu starten und einige Daten an die neue Aktivität zu übergeben, wenn Sie sie benötigen Damit die im Hintergrund laufende Aktivität zurückkehren kann, kann es zu einem kleinen Problem kommen, wenn Sie zur Rezeption gehen und einige Daten weitergeben.
Wenn Sie eine Aktivität durch Absicht starten, erstellt das System zunächst standardmäßig eine neue Aktivitätsinstanz und zeigt diese an, auch wenn bereits eine identische laufende Aktivität vorhanden ist. Um zu verhindern, dass die Aktivität mehrmals instanziiert wird, müssen wir den Lademodus (launchMode) der Aktivität in AndroidManifest konfigurieren. Wenn das System bereits über eine Instanz verfügt, sendet das System die Anforderung an diese Instanz. Zu diesem Zeitpunkt ruft das System jedoch nicht die onCreate-Methode auf, die normalerweise die Anforderungsdaten verarbeitet, sondern die onNewIntent-Methode
Antwort:Voraussetzung: AktivitätA hat wurde gestartet und befindet sich im Aktivitätsstapel der aktuellen Anwendung; Wenn der LaunchMode von ActivityA SingleTop ist, sich ActivityA oben im Stapel befindet und Sie ActivityA erneut starten möchten, wird die Methode onNewIntent() aufgerufen. Wenn der LaunchMode von ActivityA SingleInstance oder SingleTask ist und sich ActivityA bereits im Stapel befindet, wird zu diesem Zeitpunkt die Methode onNewIntent() aufgerufen
Wenn der LaunchMode von ActivityA Standard ist, wird jedes Mal, wenn ActivityA gestartet wird, ein neues The Die Instanz hat nichts mit dem ursprünglichen Start zu tun, daher wird die onNewIntent-Methode der ursprünglichen ActivityA nicht aufgerufen. Die onCreate-Methode wird weiterhin aufgerufen
Das Folgende ist ein Codebeispiel
1. Legen Sie den Start von MainActivity fest. Der Modus ist SingleTask (In-Stack-Wiederverwendung)<activity
android:label="@string/app_name"android:launchmode="singleTask"android:name="Activity1">
</activity>复制代码
<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>复制代码
**Hier ist ein Video einer vollständigen systematischen High-Level-Architektur ; **Sieben Mainstream-Technologiemodule, Video + Quellcode + Notizen ( )3 Vorteile von RecyclerView im Vergleich zu ListView Zunächst müssen wir den Namen von RecyclerView erklären. Ausgehend von seinem Klassennamen ist die Bedeutung von RecyclerView dass ich mich nur um Recycler View kümmere, was bedeutet, dass RecyclerView nur Ansichten recycelt und wiederverwendet. Den Rest können Sie selbst einrichten. Es ist ersichtlich, dass der hohe Grad der Entkopplung Ihnen volle Anpassungsfreiheit bietet (so dass Sie über dieses Steuerelement problemlos ListView, GirdView, Wasserfallfluss und andere Effekte erzielen können). Zweitens bietet RecyclerView die Möglichkeit, und hinzuzufügen Elemente löschen. Animationseffekte und können angepasst werden Der Vorteil von RecyclerView im Vergleich zu ListView besteht darin, dass es einfach implementiert werden kann: jcodecraeer.com/a/anzhuokai…
blog.csdn.net/lmj62356579…
www.360doc.com/content/16/… Antwort: Proguard-Technologie Es hat die folgenden Funktionen: Komprimierung – nutzlose Klassen im Code prüfen und entfernen
Optimierung – Optimieren Sie den Bytecode und entfernen Sie nutzlosen Bytecode
Verschleierung – Verschleiern Sie den Namen der Definition, um eine Dekompilierung zu vermeiden. Vorabüberwachung – Erkennen Sie den verarbeiteten Code erneut auf der Java-Plattform. Code-Verschleierung wird nur verwendet, wenn Sie online gehen und debuggen. Es wird deaktiviert ausgeschaltet im Modus und ist eine optionale Technologie. Warum also Code-Verschleierung verwenden? Da Java eine plattformübergreifend interpretierte Entwicklungssprache ist und der Quellcode von Java in Bytes kompiliert wird, werden Codedateien gespeichert In .class-Dateien enthält der Java-Bytecode aufgrund plattformübergreifender Anforderungen viele Quellcodeinformationen, z. B. Variablennamen, Methodennamen usw. Und viele dieser Variablen sind bedeutungslos, aber sie lassen sich leicht in Java-Quellcode dekompilieren. Um dieses Phänomen zu verhindern, müssen wir den Java-Bytecode verschleiern und neu organisieren Verarbeiten Sie das freigegebene Programm so, dass der verarbeitete Code dieselbe Funktion und eine andere Codeanzeige hat als der vorverarbeitete Code. Selbst wenn er dekompiliert wird, ist es schwierig, die Bedeutung des Codes zu verstehen und herauszufinden, welcher Code verschleiert wurde weiterhin gemäß der vorherigen Logik ausgeführt werden und das gleiche Ergebnis erhalten. Einige Java-Klassen können jedoch nicht verwechselt werden. Beispielsweise können Java-Klassen, die die Serialisierung implementieren, nicht verwechselt werden, da sonst Probleme bei der Deserialisierung auftreten. Wenn Sie den folgenden Code verschleiern, achten Sie bitte darauf, ihn beizubehalten und nicht zu verschleiern. Andere offizielle Anroid-Empfehlungen sind nicht verwirrend, wie zum Beispiel In Android wird die Reaktionsfähigkeit von Anwendungen durch zwei Systemdienste überwacht: Aktivitätsmanager und Fenstermanager. Wenn der Benutzer ein Eingabeereignis auslöst (z. B. Tastatureingabe, Tastenklick usw.) und die Anwendung nicht innerhalb von 5 Sekunden auf das Eingabeereignis des Benutzers reagiert, geht Android davon aus, dass die Anwendung nicht reagiert, und öffnet das ANR-Dialogfeld. Die ANR-Ausnahme wird hauptsächlich angezeigt, um die Benutzererfahrung zu verbessern. Die Lösung besteht darin, dass Sie für zeitaufwändige Vorgänge wie den Zugriff auf das Netzwerk, den Zugriff auf die Datenbank usw. einen Unterthread öffnen und die zeitaufwändigen Vorgänge im Unterthread verarbeiten müssen. Der Hauptthread implementiert hauptsächlich UI-Operationen Der Prozess der Verwendung des Handlers im Hauptthread Erstellen Sie zunächst ein Handler-Objekt im Hauptthread und schreiben Sie die handleMessage()-Methode neu. Wenn dann die Benutzeroberfläche im untergeordneten Thread aktualisiert werden muss, erstellen wir ein Message-Objekt und senden die Nachricht über den Handler. Danach wird die Nachricht zur MessageQueue-Warteschlange hinzugefügt, um auf die Verarbeitung zu warten. Das Looper-Objekt versucht immer, die ausstehende Nachricht aus der Message Queue abzurufen und sie schließlich an die Handler-Message()-Methode des Handlers zu verteilen. Referenz blog.csdn.net/u012827296/… www .cnblogs.com/yangtao1995… Antwort: Mein persönliches Verständnis ist, dass das Rendern der Android-Ansicht drei Schritte durchlaufen muss: Messen, Layouten und Zeichnen. Der Messprozess wird kontinuierlich in einer Baumstruktur durchlaufen viel Zeit, daher sollten Sie versuchen, den Verschachtelungsgrad so weit wie möglich zu reduzieren, die Baumstruktur flach zu halten und Ansichten zu entfernen, die nicht gerendert werden müssen Schritte für benutzerdefinierte Ansichten: Allgemeine Schritte für die benutzerdefinierte Android-Ansicht Volley-Tutorial blog.csdn. net/jdfkldjlkjd… Grundlegender Unterschied zwischen TCP und UDP UDP-Anwendungsszenarien: Einzelfallmodus: Singleton-Modus Dies ist ein Objekterstellungsmodus, der zum Generieren einer bestimmten Instanz eines Objekts verwendet wird. Er kann sicherstellen, dass nur eine Instanz einer Klasse im System generiert wird. Adaptermodus: Konvertieren Sie eine Schnittstelle in eine andere Schnittstelle, die der Kunde wünscht. Der Adaptermodus ermöglicht die Zusammenarbeit von Klassen mit inkompatiblen Schnittstellen. Dekorationsmodus: Dynamisch hinzufügen Einige zusätzliche Verantwortlichkeiten für ein Objekt sind im Hinblick auf das Hinzufügen von Objektfunktionen flexibler als das Generieren von Unterklassenimplementierungen. Dekorationsmuster ist ein Objektstrukturmuster. Nutzungsszenarien: Vorteile: Um die Funktion eines Objekts zu erweitern, ist der Dekorationsmodus flexibler als die Vererbung und führt nicht zu einem starken Anstieg in der Anzahl der Klassen. kann die Funktionalität eines Objekts auf dynamische Weise erweitern. Ein Objekt kann mehrfach dekoriert werden, indem verschiedene spezifische Dekorationsklassen und die Permutationen und Kombinationen dieser Dekorationsklassen verwendet werden. Praktische Anwendung: Implementierung der Kontextklasse in Android Darstellungsmodus: Der Hauptzweck besteht darin, die Anzahl externer und zu reduzieren Interne Subsysteme Die Interaktion zwischen Modulen erleichtert der Außenwelt die Nutzung des Subsystems. Es ist dafür verantwortlich, Clientanfragen zur Verarbeitung an verschiedene Module innerhalb des Subsystems weiterzuleiten. Nutzungsszenarien: ** Kombinationsmodus: ** Organisieren Sie Objekte in einer Baumstruktur, um eine „Teil-Ganze“-Hierarchie zu erreichen, sodass der Client einzelne Objekte und kombinierte Objekte konsistent verwenden kann . Verwendungsszenarien: Vorteile: 1. Modulaufrufe auf hoher Ebene sind einfach
2. Knoten frei hinzufügen ** Vorlagenmethode: ** besteht darin, die Schritte im Algorithmus über ein Algorithmusskelett zu verzögern, sodass Unterklassen die Implementierung dieser Schritte überschreiben können, um bestimmte Algorithmen zu implementieren. Seine Verwendungsszenarien: Ein abstraktes Modell hat zwei Aspekte, von denen einer vom anderen abhängt Zum Beispiel Im Rückrufmodus wird die Methode an die übergeordnete Klasse zurückgegeben, nachdem die Instanz, die die abstrakte Klasse/Schnittstelle implementiert, die von der übergeordneten Klasse bereitgestellte abstrakte Methode implementiert, um notifyDataSetChanged in Listview Verwendungsszenarien: Praktische Anwendung: ** Strategiemuster: ** Definieren Sie eine Reihe von Algorithmen, kapseln Sie sie einzeln und machen Sie sie austauschbar. Dieses Muster ermöglicht es dem Algorithmus, sich unabhängig vom Client zu ändern, der ihn verwendet. Verwendungsszenarien des Strategiemusters: Eine Klasse definiert eine Vielzahl von Verhaltensweisen, und diese Verhaltensweisen erscheinen in Form mehrerer bedingter Anweisungen in den Methoden dieser Klasse. Anschließend kann das Strategiemuster verwendet werden, um die Verwendung einer großen Anzahl bedingter Anweisungen zu vermeiden die Klasse. Verwendungsszenario: Vorteile: Spezifische Anwendungen: HttpStack blog.csdn.net/u010652002/… Antwort: blog.csdn.net/xmc28114194… Antwort: Immer wenn Sie die Datenbank verwenden müssen, müssen Sie die openDatabase()-Methode von DatabaseManager verwenden, um die zu erhalten Diese Methode verwendet einen einzigen Beispielmodus, um die Einzigartigkeit von Datenbankobjekten sicherzustellen, dh die bei jedem Betrieb der Datenbank verwendeten SQLite-Objekte werden konsistent abgerufen. Zweitens verwenden wir einen Referenzzähler, um zu bestimmen, ob ein Datenbankobjekt erstellt werden soll. Wenn der Referenzzähler 1 ist, müssen wir eine Datenbank erstellen. Wenn er nicht 1 ist, haben wir ihn bereits erstellt.
In der Methode closeDatabase() beurteilen wir auch den Wert des Referenzzählers. Wenn der Referenzzähler auf 0 sinkt, bedeutet dies, dass wir die Datenbank schließen müssen. Der allgemeine Ansatz besteht darin, dass Sie im Fall eines Multithread-Zugriffs einen DatabaseManager kapseln müssen, um das Lesen und Schreiben der SQLite-Datenbank zu verwalten. Es ist eine Synchronisierung erforderlich, die asynchron ist und nicht direkt ausgeführt werden kann die Datenbank, was leicht passieren kann. Der Vorgang nach dem Sperren ist aufgrund des Sperrproblems fehlgeschlagen. Diese Antwort bezieht sich auf diesen Artikel blog.csdn.net/rockcode_li... Analyse: Leetcode Der Schnittpunkt zweier verknüpfter Listen www.360doc.com/content/16/… Es gibt die folgenden Ideen: (1) Brute-Force-Cracking Durchlaufen Sie alle Knoten der verknüpften Liste A und vergleichen Sie jeden Knoten mit allen Knoten in der verknüpften Liste B. Die Ausgangsbedingung besteht darin, den ersten gleichen Knoten in B zu finden. Die Zeitkomplexität beträgt O(LängeA*LängeB) und die räumliche Komplexität beträgt O(1). (2) Hash-Tabelle. Durchlaufen Sie die verknüpfte Liste A und speichern Sie die Knoten in der Hash-Tabelle. Durchlaufen Sie dann die verknüpfte Liste B und durchsuchen Sie die Hash-Tabelle für jeden Knoten in B. Wenn er in der Hash-Tabelle gefunden wird, bedeutet dies, dass es sich um den Knoten handelt, an dem der Schnittpunkt beginnt. Die zeitliche Komplexität beträgt O (Länge A + Länge B) und die räumliche Komplexität beträgt O (Länge A) oder O (Länge B). (3) Doppelzeigermethode, die Zeiger pa und pb zeigen auf die ersten Knoten der verknüpften Listen A bzw. B. Durchlaufen Sie die verknüpfte Liste A und zeichnen Sie ihre Länge LängeA auf, durchlaufen Sie die verknüpfte Liste B und zeichnen Sie ihre Länge LängeB auf. Da die Längen der beiden verknüpften Listen unterschiedlich sein können, zum Beispiel in dem in der Frage angegebenen Fall, LängeA = 5, LängeB = 6, dann ist der Unterschied LängeB-LängeA = 1 und der Zeiger pb wird vom ersten Knoten der verknüpften Liste B geändert. Beginnen Sie mit einem Schritt, der auf den zweiten Knoten zeigt, und pa zeigt auf den ersten Knoten der verknüpften Liste A. Dann führen sie gleichzeitig einen Schritt aus. Sie sind die Schnittpunkte. Heutzutage ist die Android-Entwicklung nicht mehr so beliebt wie in den Vorjahren, aber hochrangige Talente sind immer noch Mangelware. Kommt Ihnen dieser Satz bekannt vor, denn auch hochrangige Webtalente sind es Mangelware und hochrangige C++-Talente sind immer noch Mangelware, daher wird es im Zeitalter der künstlichen Intelligenz auch einen Mangel an hochrangigen Talenten geben! Es scheint, dass hochtalentierte Menschen auch hochrangige Talente in anderen Bereichen sind, und es ist nicht so, dass sie einen reibungslosen Ablauf haben, weil sie sich für die beliebten entscheiden. Es gibt eine gemischte Sammlung von Artikeln zu Interviews mit leitenden Ingenieuren im Internet, entweder zu viele Inhalte oder die Qualität der Inhalte ist zu gering Ich habe die folgenden Fragen und Antworten zum leitenden Android-Entwicklungsingenieur zusammengestellt, um Ihnen zu helfen. Derzeit arbeite ich als leitender Android-Ingenieur in einem großen Hersteller Beitrag zu Android-Ingenieuren Ich habe diese Fragen sorgfältig geprüft und bin der Meinung, dass sie gut sind. Ich weiß, dass leitenden Ingenieuren keine Fragen gestellt werden, die in ein oder zwei Sätzen klar ausgedrückt werden können, also ich Ich habe die Artikel gefiltert, um allen das Verständnis zu erleichtern, und ich hoffe, dass sie für alle hilfreich sind. Das obige ist der detaillierte Inhalt vonEine Zusammenstellung von Problemen, auf die Android-Entwickler in Interviews mit Alibaba und anderen großen Herstellern gestoßen sind. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!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....");
}
}复制代码
Referenz bereitstellen
4. Sprechen Sie über die Proguard-Verschleierungstechnologie
5. Szenarien und Lösungen für ANR
Der Prozess der SSL-Zertifikatauthentifizierung in HTTPS
Beschreiben Sie kurz den internen Mechanismus der Android-Aktivität
8 Einführung in ein bestimmtes Modul (oder eine System-App) der Android Framework-Ebene
9 Der Mechanismus und das Prinzip des Android-Handlers
10. Was ist der Unterschied zwischen Inter-Thread-Kommunikation und Inter-Prozess-Kommunikation und wie wird sie im Android-Entwicklungsprozess implementiert
11. Beschreiben Sie kurz einige Details der Speicheroptimierung im Projekt
12. Beschreiben Sie kurz die Optimierung der Ansichtsebene von Android und beschreiben Sie kurz die benutzerdefinierte Ansicht oder die benutzerdefinierten Schritte beim Definieren von ViewGroup
13. Wählen Sie eine häufig verwendete Open-Source-Bibliothek eines Drittanbieters aus und beschreiben Sie kurz deren Zugriffsschritte
Der Unterschied zwischen TCP und UPD und Nutzungsszenarien
15. Beschreiben Sie kurz das Konzept eines Entwurfsmusters und sprechen Sie kurz darüber, welche Entwurfsmuster in der Framework-Ebene verwendet werden
Seine Verwendungsszenarien:
Spezifische Anwendung:Volley Framework
Die Grundeinheit des Byte-Stream-Betriebs ist Byte; die Grundeinheit des Zeichen-Stream-Betriebs ist die Unicode-Codeeinheit (2 Bytes).
Byteströme verwenden standardmäßig keine Puffer; Zeichenströme verwenden Puffer. Byte-Stream wird normalerweise zum Verarbeiten von Binärdaten verwendet. Tatsächlich kann er jede Art von Daten verarbeiten, unterstützt jedoch nicht das direkte Schreiben oder Lesen von Unicode-Codeelementen. Der Zeichenstream verarbeitet normalerweise Textdaten und unterstützt das Schreiben und Unicode-Codeelemente lesen. Siehe den Unterschied zwischen Zeichenstrom und Bytestrom in Java verstehen17 Ansichtszeichnungsprozess, ob zuerst die übergeordnete Ansicht oder zuerst die untergeordnete Ansicht gemessen werden sollAnsicht und ViewGroup Der grundlegende Zeichenprozess 18. Können OOM-Ausnahmen durch try...catch abgefangen werden (oder kann ein Out-of-Memory-Fehler mit try-catch erfasst werden, um sein Auftreten zu vermeiden?) Nur eins In diesem Fall ist dies möglich: In der Try-Anweisung wird ein großes Objekt deklariert, das OOM verursacht, und durch die Objektdeklaration in der Try-Anweisung kann bestätigt werden, dass das OOM verursacht wird, dann können diese Objekte sein In der Catch-Anweisung freigegeben, das OOM-Problem lösen und mit der Ausführung der verbleibenden Anweisungen fortfahren. Aber das ist meist nicht der richtige Ansatz. Zusätzlich zum expliziten Abfangen von OOM gibt es in Java effektivere Möglichkeiten zur Speicherverwaltung: z. B. SoftReference, WeakReference, Festplatten-Cache usw. Bevor der JVM der Speicher ausgeht, wird GC mehrmals ausgelöst, und diese GCs verringern die Effizienz des Programmbetriebs. Wenn die Ursache von OOM nicht das Objekt in der try-Anweisung ist (z. B. ein Speicherverlust), wird OOM weiterhin in der Catch-Anweisung geworfen19 Der Unterschied zwischen WeakReference und SoftReferenceJava's StrongReference, SoftReference, Der Unterschied zwischen WeakReference und PhantomReference20. Bitte berechnen Sie den Speicher, der von einem 100 Pixel * 100 Pixel großen Bild belegt wird
21. Prinzip der okHttp-Implementierung
22. Welche Abfangjäger hat okHttp
23? +3! +4! +5! Das Ergebnis von +...+20! ist im Code implementiert
24 Schreiben Sie den Singleton-Modus, welche Thread-sicher sind und warum sie Thread-sicher sind
25 Prinzip
26.Was sind die Formate von Android-Bildern?
27. Kann SQLite Multithread-Operationen ausführen? um einen Multithread-Datenbankbetrieb zu gewährleisten Sicherheit
28. Es gibt zwei verknüpfte Listen mit bekannten Längen
Ende