// qo'shish $1
Golang
Agar o'zing kodingiz uchun birlik testlarini yozgan bo'lsangiz, qaysilarini yozgan bo'lar edingiz? Qaysi chekka holatlarni tekshirgan bo'lar edingiz?
Idempotlik uchun voqea ID sini qayerdan olish va uni qayerda yaratish kerak?
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 }
SQL darajasida qanday qilib allaqachon idempotentlik kaliti mavjudligini tushunish mumkin? ON CONFLICT qanday ishlatiladi?
Qayerda loglarni saqladingiz, kodda qaysi loglash paketidan foydalandingiz va loglar stdout dan Elasticsearch ga qanday o'tdi?
Loyihani/ish taklifini haqida gapirib bering: texnologiyalar steki, jamoa vazifalari
Agar tranzaksiya tasdiqlanmasa, outboxdagi ID bilan nima bo'ladi?
Kodiqda qanday boshqa global muammolar mavjud? Pulni qanday saqlash mumkin — float ishlatish mumkinmi?
sql.DB ni qiymat sifatida nusxalash muammosi nima, ko'rsatkich bilan emas?
Loglar qancha vaqt saqlandi va Kafka'da ma'lumotlar qancha vaqt saqlandi?
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) // tranzaksiya qo'shish 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 qo'shish if err != nil { if err == sql.ErrNoRows { return p, errors.New("hamkor topilmadi") } return p, err } return p, nil }
func (p *Pool) Stop() { p.mu.Unlock() // Endi mumkin xavfsiz tarzda kanalni yopish close(p.tasks) // signal ishchilarga: yangi vazifa bo'lmaydi, qolganini o'qing p.wg.Wait() // barcha goroutine'lar tugashini kutamiz p.cancel() // ehtiyot chorasi sifatida kontekstni bekor qilamiz fmt.Println("Pool to'xtatildi.") } // ForceStop majburan barcha ishchilarni vazifalar tugashini kutmasdan to'xtatadi. // Ishchilar darhol kontekst orqali to'xtatiladi. func (p *Pool) ForceStop(timeout time.Duration) { fmt.Printf("Majburan to'xtatish (timeout: %v)...\n", timeout) // Yangi vazifalarni qo'shishni bloklaydi p.mu.Lock() p.isOpen = false p.mu.Unlock() // Kanalni yopamiz, shunda ishchilar yangi vazifa olmaydi close(p.tasks) // Kontekstni bekor qilamiz – bu bajarilayotgan barcha vazifalarni to'xtatadi p.cancel() // Yakunlash uchun cheklangan vaqt beramiz done := make(chan struct{}) go func() { p.wg.Wait() close(done) }() select { case <-done: fmt.Println("Pool majburan to'xtatildi (barcha ishchilar tugadi)") case <-time.After(timeout): fmt.Println("Pool majburan to'xtatildi (timeout, qolgan goroutine'lar bo'lishi mumkin)") } }
func (r *PayoutRepository) Payout(advertiserID, partnerID string, amount float32) error { advertiser, err := r.find(advertiserID) // tranzaktsiya qo'shish if err != nil { return err } partner, err := r.find(partnerID) if err != nil { return err } advertiser.Balance -= amount // SELECT FOR UPDATE ni himoya qilish 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 }
Ushbu ekran tasviridan suhbat savoli/vazifasini chiqarib oling. Asl tilni saqlang.
/* Tartiblangan ketma-ketlikda bo‘lgan butun sonlar a, indeks index va butun son k berilgan. Ro‘yxatdan a[index] elementiga eng yaqin bo‘lgan k sonni istalgan tartibda qaytarish kerak. 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] yoki [5, 7] */
Algoritm kontekstida ld, rd := 1<<62, 1<<62 nima?
Kafka xabarida aniq nima yozish kerak? Qaysi maydonlarni iste'molchilarga uzatish kerak?
Berilgan tartiblangan, kamayish bo'yicha emas, tartiblangan butun sonlar ro'yxati a, element indeksini index va butun son k. Ro'yxatdan a[index] elementiga eng yaqin bo'lgan k ta sonni istalgan tartibda qaytarish kerak. 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] yoki [5, 7]