// adj hozzá $1
Golang
Ha te írnál egységteszteket a kódodhoz, melyeket írnál? Milyen sarokeseteket ellenőriznél?
Hol tároltad a naplókat, melyik naplózási csomagot használtad a kódban, és hogyan kerültek a naplók a stdout-ból az Elasticsearch-be?
Honnan szerezhető be az esemény azonosítója az idempotencia érdekében, és hol generálható?
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 }
Hogyan lehet SQL szinten megérteni, hogy már létezik ilyen idempotencia kulcs? Hogyan használjuk az ON CONFLICT-ot?
Mesélj a projektről/állásajánlatról: technológiai stack, a csapat feladatai
Milyen más globális problémák vannak a kódban? Hogyan tároljuk a pénzt — lehet float-ot használni?
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(advertiserID) // tranzakció hozzáadása if err != nil { return err } partner, err := r.find(partnerID) if err != nil { return err } advertiser.Balance -= amount // SELECT FOR UPDATE védelme 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 }
Mi történik az ID-vel az outboxban, ha a tranzakció nem kerül megerősítésre?
/* Egy nem csökkenő sorrendben rendezett egész számok listája a, egy index index és egy egész k. Vissza kell adni bármilyen sorrendben k számot a listából, amelyek a legközelebb vannak az a[index] értékéhez. 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] vagy [5, 7] */
func (p *Pool) Stop() { p.mu.Unlock() // Most már biztonságosan bezárhatjuk a csatornát close(p.tasks) // jelzés a munkásoknak: nem lesz több feladat, olvassa a maradékot p.wg.Wait() // várjuk, hogy minden goroutine befejeződjön p.cancel() // szükség esetén töröljük a kontextust fmt.Println("Pool leállítva.") } // ForceStop kényszeríti az összes munkást, hogy befejezés nélkül álljanak le. // A munkások azonnal megszakítódnak a kontextuson keresztül. func (p *Pool) ForceStop(timeout time.Duration) { fmt.Printf("Kényszerített leállítás (timeout: %v)...\n", timeout) // Blokkolja az új feladatok hozzáadását p.mu.Lock() p.isOpen = false p.mu.Unlock() // Bezárja a csatornát, hogy a munkások ne vegyenek fel új feladatokat close(p.tasks) // A kontextus megszakítása – ez minden futó feladatot megszakít p.cancel() // Korlátozott időt ad a befejezéshez done := make(chan struct{}) go func() { p.wg.Wait() close(done) }() select { case <-done: fmt.Println("Pool kényszerített leállítása (minden munkás befejeződött)") case <-time.After(timeout): fmt.Println("Pool kényszerített leállítása (timeout, maradhatnak függő goroutine-ok)") } }
Mi a probléma az sql.DB érték szerinti másolásával a mutató helyett?
Meddig tárolták a naplókat és meddig tárolták az adatokat Kafka-ban?
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 (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(totalPayouts) // tranzakció hozzáadása 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 hozzáadása if err != nil { if err == sql.ErrNoRows { return p, errors.New("partner nem található") } return p, err } return p, nil }
Vágja ki az interjú kérdését/feladatát ebből a képernyőképből. Tartsa meg az eredeti nyelvet.
Mit írjunk pontosan a Kafka üzenetbe? Milyen mezőket továbbítsunk a fogyasztóknak?
Mi az az ld, rd := 1<<62, 1<<62 az algoritmus kontextusában?
tárolási csomag import ( "database/sql" "errors" "fmt" "time" "github.com/company/my-service/internal/event" "github.com/company/my-service/internal/metric" ) type Partner struct { ID string `db:"id" json:"id"` Balance float32 `db:"balance" json:"balance"` Hold float32 `db:"hold" json:"hold"` } type PayoutRepository struct { db sql.DB eventPublisher event.Publisher metricCollector metric.Collector totalPayouts int } func NewPayoutRepository() *PayoutRepository { db, err := sql.Open("postgres", "host=localhost user=postgres password=postgres dbname=affiliate") if err != nil { panic(err) } r := PayoutRepository{ db: db, eventPublisher: event.NewKafkaPublisher("localhost:9092"), metricCollector: metric.NewPrometheusCollector("localhost:9090"), } go func() { for range time.Tick(time.Minute) { _ = r.metricCollector.Send("TotalPayouts", r.totalPayouts) } }() return r } 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 } func (r *PayoutRepository) find(id string) (Partner, error) { p := Partner{} err := r.db.QueryRow("SELECT * FROM partners WHERE id = " + id).Scan(&p) if err != nil { if err == sql.ErrNoRows { return p, errors.New("partner not found") } return p, err } return p, nil } 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 }