Heim  >  Artikel  >  Web-Frontend  >  Eine Zusammenstellung von Problemen, auf die Android-Entwickler in Interviews mit Alibaba und anderen großen Herstellern gestoßen sind

Eine Zusammenstellung von Problemen, auf die Android-Entwickler in Interviews mit Alibaba und anderen großen Herstellern gestoßen sind

藏色散人
藏色散人nach vorne
2020-07-31 14:14:584013Durchsuche

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.

1. So vermeiden Sie Speicherlecks beim Anpassen des Handlers

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...

Der Aufrufzeitpunkt von onNewIntent( )

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)

6b4b8de82f5ec1f2a7986e15ef3b7143
abedf4926b16e78349669730db0843a2复制代码

2. Überschreiben Sie die onNewIntent-Methode in MainActivity

<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 führt Click Jump aus, MainActivity wird wiederverwendet und die onNewIntent-Methode wird ausgeführt

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....");
}
}复制代码
Screenshots drucken

**Hier ist ein Video einer vollständigen systematischen High-Level-Architektur ; **Sieben Mainstream-Technologiemodule, Video + Quellcode + Notizen (

Am Ende des Artikels gibt es ein detailliertes Spezialpaket mit Interviewmaterialien

)3 Vorteile von RecyclerView im Vergleich zu ListView

Analyse:

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:

ListView-Funktionen
  1. GridView-Funktionen
  2. Funktionen der horizontalen ListView
  3. Funktion der horizontalen ScrollView
  4. Wasserfalleffekt
  5. Einfach hinzuzufügende Animationen zum Hinzufügen und Entfernen von Elementen
  6. Aber es ist ziemlich deprimierend. Das Problem ist, dass das System keinen ClickListener und keinen LongClickListener bereitstellt. Wir können es aber auch selbst hinzufügen, es erfordert nur mehr Code. Es gibt viele Möglichkeiten, dies zu implementieren. Sie können Gesten über mRecyclerView.addOnItemTouchListener abhören und beurteilen. Natürlich können Sie auch selbst Rückrufe über den Adapter

Referenz bereitstellen

jcodecraeer.com/a/anzhuokai… blog.csdn.net/lmj62356579… www.360doc.com/content/16/…

4. Sprechen Sie über die Proguard-Verschleierungstechnologie

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.

  • Android-Systemkomponenten, Systemkomponenten verfügen über feste Methoden, die vom System aufgerufen werden.
  • wird von der Android-Ressourcendatei referenziert. Der Name wurde festgelegt und kann nicht mit einer benutzerdefinierten Ansicht verwechselt werden.
  • Android Parcelable, muss Android-Serialisierung verwenden.

Andere offizielle Anroid-Empfehlungen sind nicht verwirrend, wie zum Beispiel

  • android.app.backup.BackupAgentHelper
  • android.preference . Präferenz 
  • com.android.vending.licensing.ILicensingService 
  • Java-Serialisierungsmethode, Systemserialisierung erfordert eine feste Methode. 
  • Aufzählung, das System benötigt eine feste Methode, um die Aufzählung zu verarbeiten.
  • Lokale Methode, Name der lokalen Methode kann nicht geändert werden
  • Anmerkungen Anmerkungen
  • Datenbanktreiber
  • Einige Ressourcendateien verwenden Reflektion

5. Szenarien und Lösungen für ANR

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 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

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/…

10. Was ist der Unterschied zwischen Inter-Thread-Kommunikation und Inter-Prozess-Kommunikation und wie wird sie im Android-Entwicklungsprozess implementiert

www .cnblogs.com/yangtao1995…

11. Beschreiben Sie kurz einige Details der Speicheroptimierung im Projekt

Antwort:

  1. Nachdem Sie die Datenbank abgefragt haben, schließen Sie das Cursor-Objekt rechtzeitig.
  2. Denken Sie daran, die Methode unregisterReceiver() in der onPause-Methode der Aktivität aufzurufen, um die Registrierung der Übertragung aufzuheben
  3. , um Inhaltsspeicherlecks zu vermeiden. Setzen Sie das Drawer-Objekt beispielsweise bei Versionen vor 4.0 nicht auf statisch .1. Wenn ein Drawable an eine Ansicht gebunden ist, wird das View-Objekt tatsächlich zu einer Callback-Mitgliedsvariablen des Drawable. Im obigen Beispiel enthält der statische sBackground einen Verweis auf das TextView-Objekt lable, und lable hat nur einen Verweis auf Activity und Die Aktivität enthält Verweise auf andere weitere Objekte. Der Lebenszyklus von sBackground ist länger als der von Activity. Wenn der Bildschirm gedreht wird, kann die Aktivität nicht zerstört werden, was zu einem Speicherverlustproblem führt.
  4. Versuchen Sie, in der Aktivität keine nicht statischen inneren Klassen zu verwenden, da nicht statische innere Klassen implizit Verweise auf externe Klasseninstanzen enthalten Deklarationszeitraum der Aktivität. Dies führt dazu, dass die Aktivität nicht normal von GC recycelt werden kann.
  5. Verwenden Sie Threads mit Vorsicht! ! Dies ist ein Fehler, den viele Leute machen: Ein Merkmal von Threads in Java ist, dass sie direkt vom GC-Stamm referenziert werden. Das heißt, die virtuelle Dalvik-Maschine enthält starke Referenzen zu allen aktivierten Threads, was dazu führt, dass GC diese Thread-Objekte niemals kann recycelt werden, es sei denn, der Thread wird manuell gestoppt und auf null gesetzt oder der Benutzer bricht den Prozess direkt ab. Wenn Sie Threads verwenden, müssen Sie daher in Betracht ziehen, den Thread rechtzeitig zu stoppen und freizugeben, wenn die Aktivität beendet wird
  6. Wenn Sie Handler verwenden, platzieren Sie ihn entweder in einer separaten Klassendatei oder verwenden Sie eine statische innere Klasse. Da statische innere Klassen keine Verweise auf externe Klassen enthalten, verursachen sie keine Speicherverluste bei externen Klasseninstanzen

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

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

13. Wählen Sie eine häufig verwendete Open-Source-Bibliothek eines Drittanbieters aus und beschreiben Sie kurz deren Zugriffsschritte

Volley-Tutorial blog.csdn. net/jdfkldjlkjd…

Der Unterschied zwischen TCP und UPD und Nutzungsszenarien

Grundlegender Unterschied zwischen TCP und UDP

  1. Verbindung- basiert und verbindungslos
  2. TCP erfordert mehr Systemressourcen und weniger UDP;
  3. UDP-Programmstruktur ist einfacher
  4. Stream-Modus (TCP) und Datagramm-Modus (UDP);
  5. TCP garantiert Datenkorrektheit, UDP kann Pakete verlieren
  6. TCP garantiert Datenreihenfolge, UDP garantiert nicht

UDP-Anwendungsszenarien:

  1. Datagrammorientierte Methode
  2. Die meisten Netzwerkdaten sind Kurznachrichten
  3. Mit einer großen Anzahl von Clients
  4. Keine besonderen Anforderungen an die Datensicherheit
  5. Die Netzwerkbelastung ist sehr hoch, aber hohe Anforderungen an die Reaktionsgeschwindigkeit

15. Beschreiben Sie kurz das Konzept eines Entwurfsmusters und sprechen Sie kurz darüber, welche Entwurfsmuster in der Framework-Ebene verwendet werden

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:

  1. Fügen Sie Verantwortlichkeiten dynamisch und transparent zu einem einzelnen Objekt hinzu, ohne andere Objekte zu beeinflussen.
  2. Der Dekorationsmodus kann verwendet werden, wenn das System nicht durch Vererbung erweitert werden kann oder wenn die Vererbung der Systemerweiterung und -wartung nicht förderlich ist.

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:

  1. Wenn Sie eine einfache Schnittstelle für ein komplexes Subsystem bereitstellen möchten
  2. Es gab eine große Abhängigkeit zwischen dem Clientprogramm und dem Implementierungsteil der abstrakten Klasse
  3. Wann Wann Sie Sie müssen ein hierarchisches Subsystem aufbauen

** 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:

  1. Muss die gesamte oder teilweise Ebene eines Objekts darstellen
  2. Ermöglichen Sie dem Client, Änderungen an verschiedenen Objekten zu ignorieren Ebenen

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:

  1. Mehrere Unterklassen haben öffentliche Methoden, und die Logik ist im Grunde dieselbe
  2. Wichtige und komplexe Algorithmen Der Kernalgorithmus kann als Vorlagenmethode entworfen werden. Das Muster der Vorlagenmethode ist ein häufig verwendetes Muster.
  3. Abhängigkeitsbeziehungen zwischen Objekten definieren Wenn sich der Status eines Objekts ändert, werden die zugehörigen abhängigen Objekte benachrichtigt und automatisch aktualisiert.

Seine Verwendungsszenarien:

Ein abstraktes Modell hat zwei Aspekte, von denen einer vom anderen abhängt
  1. Ein Objekt, das Änderungen verursacht ein oder mehrere andere Objekte sollen sich ebenfalls ändern
  2. Eine Triggerkette muss im System erstellt werden
Spezifische Anwendung:

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

im RxJava Observer-Muster

**Verantwortungskettenmodus:** Eine Anfrage wird von mehreren Objekten verarbeitet, aber welches Objekt verarbeitet wird, wird basierend auf der bedingten Beurteilung bestimmt wird an das nächste Objekt in der Kette weitergegeben, bis ein Objekt es verarbeitet.

Verwendungsszenarien:

1. Es gibt mehrere Objekte, die dieselbe Anfrage verarbeiten können. Das spezifische Objekt, das die Anfrage verarbeitet, wird zur Laufzeit bestimmt. 2. Senden Sie eine Anfrage an eines von mehreren Objekten, ohne den Empfänger explizit anzugeben.

Praktische Anwendung:

Versuchen Sie...fangen Sie die Aussage Bestellte Sendung MotionEvent:actionDwon actionMove actionUp Drei wichtige Methoden des Ereignisverteilungsmechanismus: „dispatchTouchEvent“. onInterceptTouchEvent

** 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:

Eine Klasse definiert mehrere Verhaltensweisen, und diese Verhaltensweisen erscheinen in Form mehrerer bedingter Anweisungen in den Methoden dieser Klasse. Anschließend können Sie das Strategiemuster zur Vermeidung von Losen verwenden von bedingten Anweisungen.

Vorteile:

1. Kontext und spezifische Strategie ConcreateStrategy sind lose gekoppelt 2. Das Strategiemuster erfüllt das Open-Close-Prinzip

Spezifische Anwendungen:

HttpStack

    Volley Framework
  1. 16. Byte Stream Der Unterschied zum Zeichenstrom
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 verstehen

17 Ansichtszeichnungsprozess, ob zuerst die übergeordnete Ansicht oder zuerst die untergeordnete Ansicht gemessen werden soll

Ansicht 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 geworfen

19 Der Unterschied zwischen WeakReference und SoftReference

Java's StrongReference, SoftReference, Der Unterschied zwischen WeakReference und PhantomReference

20. Bitte berechnen Sie den Speicher, der von einem 100 Pixel * 100 Pixel großen Bild belegt wird

blog.csdn.net/u010652002/…

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?

Antwort: blog.csdn.net/xmc28114194…

27. Kann SQLite Multithread-Operationen ausführen? um einen Multithread-Datenbankbetrieb zu gewährleisten Sicherheit

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...

28. Es gibt zwei verknüpfte Listen mit bekannten Längen

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.

Ende

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen