// hinzufügen $1
Golang
Wenn du eigene Unit-Tests für deinen Code schreiben würdest, welche würdest du schreiben? Welche Randfälle würdest du überprüfen?
Woher das Ereignis-ID für die Idempotenz nehmen und wo es generieren?
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(advertiserID) if err != nil { return err } partner, err := r.find(partnerID) if err != nil { return err } advertiser.Balance -= amount partner.Hold -= amount partner.Balance += amount if err := r.save(advertiser); err != nil { return err } if err := r.save(partner); err != nil { return err } r.totalPayouts++ return nil }
Wo haben Sie die Logs gespeichert, welches Logging-Paket haben Sie im Code verwendet und wie kamen die Logs von stdout zu Elasticsearch?
Wie erkennt man auf SQL-Ebene, dass bereits ein Idempotenzschlüssel vorhanden ist? Wie verwendet man ON CONFLICT?
Erzählen Sie mir vom Projekt/Jobangebot: Technologiestack, Aufgaben des Teams
Was passiert mit der ID im Outbox, wenn die Transaktion nicht abgeschlossen wird?
Welche weiteren globalen Probleme gibt es im Code? Wie man Geld speichert — kann man float verwenden?
Was ist das Problem beim Kopieren von sql.DB nach Wert anstatt nach Zeiger?
Wie lange wurden die Protokolle gespeichert und wie lange wurden die Daten in Kafka gespeichert?
func (r *PayoutRepository) save(p Partner) error { _, err := r.db.Exec( fmt.Sprintf("UPDATE partners SET balance = %s, hold = %s WHERE id = %s", p.Balance, p.Hold, p.ID), ) if err != nil { return err } if err := r.eventPublisher.Publish("BalanceChanged", p); err != nil { return err } return nil }
func (p *Pool) Stop() { p.mu.Unlock() // Jetzt kann der Kanal sicher geschlossen werden close(p.tasks) // Signal an die Worker: keine neuen Aufgaben, den Rest lesen p.wg.Wait() // Warten, bis alle Goroutines beendet sind p.cancel() // Kontext bei Bedarf abbrechen fmt.Println("Pool gestoppt.") } // ForceStop stoppt alle Worker zwangsweise, ohne auf das Ende der Aufgaben zu warten. // Die Worker werden sofort über den Kontext abgebrochen. func (p *Pool) ForceStop(timeout time.Duration) { fmt.Printf("Zwangsstopp des Pools (Timeout: %v)...\n", timeout) // Blockiert das Hinzufügen neuer Aufgaben p.mu.Lock() p.isOpen = false p.mu.Unlock() // Schließt den Kanal, damit die Worker keine neuen Aufgaben mehr nehmen close(p.tasks) // Kontext abbrechen – das unterbricht alle laufenden Aufgaben p.cancel() // Begrenzte Zeit für den Abschluss done := make(chan struct{}) go func() { p.wg.Wait() close(done) }() select { case <-done: fmt.Println("Pool zwangsweise gestoppt (alle Worker beendet)") case <-time.After(timeout): fmt.Println("Pool zwangsweise gestoppt (Timeout, es könnten hängen gebliebene Goroutines verbleiben)") } }
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(advertiserID) // Transaktion hinzufügen if err != nil { return err } partner, err := r.find(partnerID) if err != nil { return err } advertiser.Balance -= amount // SELECT FOR UPDATE schützen partner.Hold -= amount partner.Balance += amount if err := r.save(advertiser); err != nil { return err } if err := r.save(partner); err != nil { return err } r.totalPayouts++ return nil }
Extrahieren Sie die Interviewfrage/Aufgabe aus diesem Screenshot. Behalten Sie die Originalsprache bei.
/* Eine aufsteigend sortierte Liste von ganzen Zahlen a, ein Index index und eine ganze Zahl k. Es ist erforderlich, beliebig k Zahlen aus der Liste zurückzugeben, die den Wert am nächsten an a[index] haben. a=[2, 3, 5, 7, 11], index=3, k=2 -> [5, 7] a=[4, 12, 15, 15, 24], index=1, k=3 -> [12, 15, 15] a=[2, 3, 5, 7, 11], index=2, k=2 -> [3, 5] oder [5, 7] */
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(totalPayouts) // Transaktion hinzufügen if err != nil { return err } partner, err := r.find(partnerID) if err != nil { return err } advertiser.Balance -= amount partner.Hold -= amount partner.Balance += amount if err := r.save(advertiser); err != nil { return err } if err := r.save(partner); err != nil { return err } r.totalPayouts++ return nil } func (r *PayoutRepository) find(id string) (Partner, error) { p := Partner{} err := r.db.QueryRow("SELECT * FROM partners WHERE id = " + id).Scan(&p) // $1 hinzufügen if err != nil { if err == sql.ErrNoRows { return p, errors.New("Partner nicht gefunden") } return p, err } return p, nil }
Was sind ld, rd := 1<<62, 1<<62 im Kontext des Algorithmus?
Was genau in die Kafka-Nachricht schreiben? Welche Felder an die Verbraucher übermitteln?
Es ist eine aufsteigend sortierte Liste von ganzen Zahlen a, ein Elementindex index und eine ganze Zahl k gegeben. Es ist erforderlich, beliebig k Zahlen aus der Liste zurückzugeben, die den Wert am nächsten an dem Element a[index] haben. a=[2, 3, 5, 7, 11], index=3, k=2 -> [5, 7] a=[4, 12, 15, 15, 24], index=1, k=3 -> [12, 15, 15] a=[2, 3, 5, 7, 11], index=2, k=2 -> [3, 5] oder [5, 7]