// dodaj $1
Golang
Gdybyś sam pisał testy jednostkowe do swojego kodu, jakie byś napisał? Jakie przypadki brzegowe sprawdziłbyś?
Skąd wziąć ID zdarzenia dla idempotencji i gdzie go generować?
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 }
Gdzie przechowywałeś logi, jakiego pakietu do logowania użyłeś w kodzie i jak logi trafiały z stdout do Elasticsearch?
Jak na poziomie SQL zrozumieć, że już istnieje klucz idempotencji? Jak używać ON CONFLICT?
Opowiedz o projekcie/ofercie pracy: stos technologii, zadania zespołu
Co się stanie z ID w outbox, jeśli transakcja nie zostanie zatwierdzona?
Jakie inne globalne problemy występują w kodzie? Jak przechowywać pieniądze — czy można użyć float?
Jaki jest problem z kopiowaniem sql.DB przez wartość, a nie przez wskaźnik?
Jak długo przechowywano logi i jak długo przechowywano dane w 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() // Teraz można bezpiecznie zamknąć kanał close(p.tasks) // sygnał dla workerów: nie będzie nowych zadań, odczytaj resztę p.wg.Wait() // czekaj na zakończenie wszystkich goroutine p.cancel() // anuluj kontekst na wszelki wypadek fmt.Println("Pool zatrzymany.") } // ForceStop wymusza zatrzymanie wszystkich workerów bez oczekiwania na zakończenie zadań. // Workerzy zostaną natychmiast przerwani przez kontekst. func (p *Pool) ForceStop(timeout time.Duration) { fmt.Printf("Wymuszone zatrzymanie puli (timeout: %v)...\n", timeout) // Blokuje dodawanie nowych zadań p.mu.Lock() p.isOpen = false p.mu.Unlock() // Zamknij kanał, aby workerzy nie brali nowych zadań close(p.tasks) // Anuluj kontekst – to przerwie wszystkie wykonywane zadania p.cancel() // Daj ograniczony czas na zakończenie done := make(chan struct{}) go func() { p.wg.Wait() close(done) }() select { case <-done: fmt.Println("Pool wymuszenie zatrzymany (wszystkie worker zakończone)") case <-time.After(timeout): fmt.Println("Pool wymuszenie zatrzymany (timeout, mogą pozostać zawieszone goroutine)") } }
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(advertiserID) // dodać transakcję if err != nil { return err } partner, err := r.find(partnerID) if err != nil { return err } advertiser.Balance -= amount // zabezpieczyć 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 }
Wyodrębnij pytanie/zadanie z wywiadu z tego zrzutu ekranu. Zachowaj oryginalny język.
/* Posortowana niemalejąco lista liczb całkowitych a, indeks index i liczba całkowita k. Należy zwrócić dowolną kolejnością k liczb z listy, które są najbliższe wartościowo elementowi 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] lub [5, 7] */
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(totalPayouts) // dodaj transakcję 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) // dodaj $1 if err != nil { if err == sql.ErrNoRows { return p, errors.New("partner nie znaleziony") } return p, err } return p, nil }
Co oznaczają ld, rd := 1<<62, 1<<62 w kontekście algorytmu?
Co dokładnie pisać w wiadomości Kafka? Jakie pola przekazywać konsumentom?
Dana jest posortowana niemalejąco lista liczb całkowitych a, indeks elementu index i liczba całkowita k. Należy zwrócić dowolną kolejność k liczb z listy, które są najbliższe wartością do elementu 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] lub [5, 7]