Gegeben ist eine Zeichenkette. Finden Sie die Anzahl der Indexpaare i und j (i <= j), zwischen denen, einschließlich, keine wiederholten Zeichen sind. Für die Zeichenkette "aba" ist die Antwort 5: [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") Für die Zeichenkette "abcb" ist die Antwort ?: aba 3 + 2 = 5 abcb 4 (a, b, c, d) + 1 (ab) + 1 (bc) + 1 (cb) + 1 (abc) = 8
Golang
Gibt es eine Frist?
/* eine Zeichenkette wird gegeben. Finde die Anzahl der Indexpaare i und j (i <= j), zwischen denen keine wiederholten Zeichen sind. Für die Zeichenkette "aba" ist die Antwort 5: können nicht nur ASCII sein [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") */
/* Wir müssen Daten von einer Quelle zu einem Verbraucher übertragen. Die Quelle liefert die Daten in kleinen Chargen (~zehn Einträge), während der Verbraucher besser mit größeren Chargen (~tausend Einträge) arbeitet. Ein echtes Beispiel ist die Übertragung von Daten aus Kafka-Queues in eine Clickhouse-Datenbank. Quelle: - Praktisch unendlich. - Die Quelle gibt nie mehr als MaxItems Datensätze bei einem Aufruf von Next zurück. - Innerhalb einer "Sitzung" (einem Aufruf der Funktion Pipe) liefert die Quelle bei jedem Aufruf von Next neue Daten. - Nach einem Neustart beginnt die Quelle jedoch an der vorherigen "bestätigten" Position, die durch cookie bestimmt wird. Daher muss jeder Wert von cookie, der von Next zurückgegeben wird, nach dem Speichern der Daten im Empfänger mit Commit bestätigt werden, und zwar in genau der Reihenfolge, in der sie von Next zurückgegeben wurden. Empfänger: - Kann nicht mehr als MaxItems auf einmal verarbeiten. Basisebene: Es ist erforderlich, die Funktion func Pipe(p Producer, c Consumer) error zu implementieren, die Daten aus der Quelle liest, sie in einen Puffer gruppiert, der nicht größer als MaxItems ist, und sie im Empfänger speichert, und anschließend den Fortschritt in der Quelle bestätigt. Schwierigkeit: Die Methoden Next, Process und Commit sind mit Netzwerkaufrufen verbunden und können ziemlich lange dauern. Um den Prozess zu beschleunigen, müssen die Prozesse Lesen, Schreiben und Fortschrittsbestätigung parallelisiert werden. Damit während Process oder Commit das Lesen aus der Quelle und die Bildung des neuen Puffers fortgesetzt werden. */ const MaxItems = 9999 type Producer interface { // Next gibt zurück: // - einen Batch von Items zur Verarbeitung // - eine cookie, die bestätigt werden muss, wenn die Verarbeitung abgeschlossen ist // - einen Fehler Next() (items []any, cookie int, err error) // Commit wird verwendet, um einen Datenbatch als verarbeitet zu markieren Commit(cookie int) error } type Consumer interface { Process(items []any) error } func Pipe(p Producer, c Consumer) error { // TODO }
Erklären Sie das Prinzip der Dependency Inversion und warum der direkte Aufruf von Repository-Methoden aus einem Use Case gegen SOLID verstößt.
Was sind die Unterschiede zwischen den Umgebungen local, dev, stage, prod?
Wie haben Sie die Tests und die Überprüfung der Korrektheit der ausgeführten Anfragen durchgeführt?
Wie überprüft JWT seine Echtheit? Wie wird sichergestellt, dass das Token nicht gefälscht ist?
Erzähle mir von Datenbanken — mit welchen hast du gearbeitet und mit welchen arbeitest du jetzt?
/* Es gibt eine Anwendung mit einer Microservice-Architektur. Ein Microservice kann durch eine Backend-Schnittstelle abstrahiert werden. Um auf eine Instanz des Microservice zuzugreifen, kann der Typ BackendImpl verwendet werden, der bereits implementiert ist. Jeder Microservice hat mehrere Dutzend laufende Instanzen, die jeweils unter ihrer eigenen Adresse addr erreichbar sind. Allerdings sind einzelne Instanzen des Microservice nicht zuverlässig: sie können abstürzen, nicht erreichbar sein oder überlastet sein. Daher müssen Sie den Typ Balancer implementieren, der ebenfalls die Backend-Schnittstelle implementiert und das Client-seitige Load-Balancing zwischen den Instanzen des Microservice durchführt, wobei jedes Mal die **am wenigsten belastete** Instanz ausgewählt wird. */ type Request interface{} type Response interface{} type Backend interface { Invoke(ctx context.Context, req Request) (Response, error) } var _ Backend = &BackendImpl{} // addr enthält ip:port einer bestimmten Instanz func NewBackend(addr string) *BackendImpl type Balancer struct { // TODO } var _ Backend = &Balancer{} // addrs enthalten die Adressen aller balancierten Instanzen func NewBalancer(addrs []string) *Balancer { // TODO }
/* Es gibt eine Anwendung mit einer Microservice-Architektur. Ein Microservice kann durch eine Schnittstelle Backend abstrahiert werden. Um auf eine Instanz des Microservice zuzugreifen, kann der Typ BackendImpl verwendet werden, der bereits implementiert ist. Jeder Microservice hat mehrere Dutzend laufende Instanzen, die jeweils unter ihrer eigenen Adresse addr zugänglich sind. Allerdings sind einzelne Instanzen des Microservice nicht zuverlässig: sie können abstürzen, nicht erreichbar sein oder überlastet sein. Daher müssen Sie einen Typ Balancer implementieren, der ebenfalls die Schnittstelle Backend implementiert und das clientseitige Load-Balancing zwischen den Instanzen des Microservice durchführt, wobei bei jeder Wahl die **wenig belastete** Instanz ausgewählt wird. */
Haben Sie Erfahrung in der Teamleitung?
Was wird zur Antwort hinzugefügt, wenn das Fenster gültig wird?
Was ist die Einschränkung eines Semaphors und eines gepufferten Kanals als Lösungen zur Begrenzung paralleler Anfragen?
Wie vergleicht man Elemente in einer Karte? Wie überprüft man, ob zwei Karten übereinstimmen?
Wie hoch war die maximale Anzahl an Anfragen pro Sekunde (RPS), die der am stärksten ausgelastete Dienst verarbeitet hat?
Schreiben Sie eine Aufgabe in der Programmiersprache Go — praktischer Abschnitt (Probleme aus dem Entwicklerleben, ohne Algorithmen): Dienst verbessern oder korrigieren. Dauer — 1,5 Stunden.
Arbeitsformat: remote, im Büro oder hybrid?
Wie macht man den Speicher konstant (Abhängigkeit von der Anzahl der eindeutigen Zeichen entfernen)?
Was ist ein JWT-Token? Woraus besteht es?