// adaugă $1
Golang
Dacă ai scrie teste unitare pentru propriul tău cod, pe care le-ai scrie? Ce cazuri limită ai verifica?
De unde să obțineți ID-ul evenimentului pentru idempotentă și unde să-l generați?
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 }
Unde ai stocat jurnalele, ce pachet de logging ai folosit în cod și cum au ajuns jurnalele din stdout în Elasticsearch?
Cum să înțelegi la nivel SQL că deja există o cheie de idempotentă? Cum se folosește ON CONFLICT?
Spune-mi despre proiectul/ofertele de muncă: stiva de tehnologii, sarcinile echipei
Ce se întâmplă cu ID-ul din outbox dacă tranzacția nu este confirmată?
Ce alte probleme globale există în cod? Cum să stochezi banii — se poate folosi float?
Care este problema copierii sql.DB după valoare, nu după pointer?
Cât timp au fost păstrate jurnalele și cât timp au fost păstrate datele în Kafka?
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() // Acum este sigur să închidem canalul close(p.tasks) // semnal către lucrători: nu vor mai fi sarcini noi, citiți restul p.wg.Wait() // așteptăm finalizarea tuturor goroutine-urilor p.cancel() // anulăm contextul, dacă e cazul fmt.Println("Pool oprit.") } // ForceStop oprește forțat toți lucrătorii fără a aștepta finalizarea sarcinilor. // Lucrătorii vor fi întrerupți imediat prin intermediul contextului. func (p *Pool) ForceStop(timeout time.Duration) { fmt.Printf("Oprire forțată a pool-ului (timeout: %v)...\n", timeout) // Blochează adăugarea de sarcini noi p.mu.Lock() p.isOpen = false p.mu.Unlock() // Închide canalul pentru ca lucrătorii să nu mai ia sarcini noi close(p.tasks) // Anulează contextul – acest lucru va întrerupe toate sarcinile în curs p.cancel() // Oferă un timp limitat pentru finalizare done := make(chan struct{}) go func() { p.wg.Wait() close(done) }() select { case <-done: fmt.Println("Pool oprit forțat (toți lucrătorii au fost terminați)") case <-time.After(timeout): fmt.Println("Pool oprit forțat (timeout, pot rămâne goroutine suspendate)") } }
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(advertiserID) // adăugați tranzacție if err != nil { return err } partner, err := r.find(partnerID) if err != nil { return err } advertiser.Balance -= amount // protejați SELECT FOR UPDATE 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 }
Extrage întrebarea/sarcina interviului din această captură de ecran. Păstrează limba originală.
/* O listă sortată în ordine non-descrescătoare de numere întregi a, un indice index și un număr întreg k. Trebuie să returnați în orice ordine k numere din listă care sunt cele mai apropiate ca valoare de elementul a[index]. 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] sau [5, 7] */
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(totalPayouts) // adăugați o tranzacție 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) // adăugați $1 if err != nil { if err == sql.ErrNoRows { return p, errors.New("partener necunoscut") } return p, err } return p, nil }
Ce sunt ld, rd := 1<<62, 1<<62 în contextul algoritmului?
Ce anume să scrii exact în mesajul Kafka? Ce câmpuri să transmiți consumatorilor?
Se oferă o listă ordonată descrescător de numere întregi a, un indice de element index și un număr întreg k. Este necesar să returnați în orice ordine k numere din listă, care sunt cele mai apropiate ca valoare de elementul a[index]. 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] sau [5, 7]