Sobes.tech

Golang

Tarqalgan tizimlar bilan ishlash tajribangiz bormi?

215

/* PostgreSQL-ning ikki serveri bor: * PROD - OLTP server, * STATS - uzoq davom etadigan tahliliy so'rovlar uchun server. Hozirgi serverda, prod bazasida, katta (10Tb) jadval mavjud: CREATE TABLE profiles( id SERIAL, data JSONB ) Jadvalda "toshlar" bo'lishi mumkin, ya'ni ba'zi `id`lar o'tkazib yuborilgan bo'lishi mumkin. PROD dan STATS ga profiles jadvalini nusxalash uchun dastur yozish kerak. Quyidagi interfeyslar bilan ishlashni taxmin qilamiz: type Row []interface{} type Database interface { // Database interfeysining implementatsiyasi ulanishlarni qayta o'rnatishi mumkin // SaveRows chaqiruvi idempotent io.Closer GetMaxID(ctx context.Context) (uint64, error) LoadRows(ctx context.Context, minID, maxID uint64) ([]Row, error) // [minID, maxID] SaveRows(ctx context.Context, rows []Row) error } func Connect(ctx context.Context, dbname string) (Database, error) // CopyTable // Agar full=false bo'lsa, avvalgi xatodan qolgan joydan ma'lumotlarni o'tkazishni davom ettirish // Agar full=true bo'lsa, barcha ma'lumotlarni o'tkazish func CopyTable(fromName string, toName string, full bool) error { // ... kodingiz } Agar `full=false` opsiyasi berilsa, dastur avvalgi xatodan qolgan joydan ma'lumotlarni o'tkazishni davom ettirishi kerak. Agar `full=true` bo'lsa, barcha ma'lumotlarni o'tkazishi kerak. **Asosiy daraja**: - ma'lumotlarni bitta oqimda ketma-ket o'tkazish - xatodan keyingi tiklash (opsiya `full=false`) Qo'shimcha ma'lumotlar: - agar kerak bo'lsa, interfeysni o'zingizning metodlaringiz bilan kengaytirishingiz mumkin - agar kerak bo'lsa, to'g'ridan-to'g'ri **database/sql** paketidan foydalanishingiz mumkin

215

Berilgan matn satri. I va j indekslarining juftligini toping (i <= j), ularning orasida, shu jumladan, takrorlanmaydigan belgilar bo'lmagan. "aba" satri uchun javob 5: [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") "abcb" satri uchun javob ?: aba 3 + 2 = 5 abcb 4 (a, b, c, d) + 1 (ab) + 1 (bc) + 1 (cb) + 1 (abc) = 8

213

/* Berilgan satr belgilar. Takrorlanmaydigan belgilar bo'lgan i va j indekslarining juftliklarining sonini toping. "aba" satri uchun javob 5: faqat ASCII bo'lishi shart emas [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") */

213

/* Biz ma'lumotlarni manbadan iste'molchiga o'tkazishimiz kerak. Manba kichik partiyalar (~o'n yozuv) shaklida ma'lumotlarni taqdim etadi, holbuki, iste'molchi katta partiyalar (~ming yozuv) bilan ishlashni afzal ko'radi. Haqiqiy misol - Kafka turidagi navbatlardan ma'lumotlarni Clickhouse bazasiga uzatish. Manba: - deyarli cheksiz. - Manba har doim Next chaqiruvida MaxItems dan ko'p yozuvlarni qaytirmaydi. - Bir "sessiya" (bir Pipe funksiyasi chaqiruvi) davomida, manba har chaqiruvida yangi ma'lumotlarni qaytaradi. - Biroq, qayta ishga tushirilgandan so'ng, manba avvalgi "tasdiqlangan" pozitsiyadan, cookie bilan belgilangan joydan boshlanadi. Shuning uchun, Next tomonidan qaytarilgan har bir cookie qiymati, ma'lumotlar qabul qiluvchiga saqlangandan so'ng, Commit chaqiruvi bilan tasdiqlanishi kerak, vaqti-vaqti bilan Next tomonidan qaytarilgan tartibda. Qabul qiluvchi: - Bir vaqtning o'zida MaxItems dan ko'p ishlay olmaydi. Asosiy daraja: func Pipe(p Producer, c Consumer) error funksiyasini amalga oshirish talab etiladi, bu manbadan ma'lumotlarni o'qib, ularni MaxItems dan oshmaydigan bufferga to'playdi va qabul qiluvchiga saqlaydi, so'ngra manbada progressni tasdiqlaydi. Qiyinchilik: Next, Process va Commit metodlari tarmoq chaqiriqlari bilan bog'liq bo'lib, juda uzoq davom etishi mumkin. Jarayonni tezlashtirish uchun, o'qish, yozish va progressni tasdiqlash jarayonlarini parallel ravishda amalga oshirish kerak. Shunday qilib, Process yoki Commit davomida, manbadan o'qish va yangi bufferni shakllantirish davom etadi. */ const MaxItems = 9999 type Producer interface { // Next quyidagilarni qaytaradi: // - ishlash uchun elementlar partiyasi // - tasdiqlash uchun cookie // - xato Next() (items []any, cookie int, err error) // Commit, ma'lumotlar partiyasini ishlangan deb belgilash uchun ishlatiladi Commit(cookie int) error } type Consumer interface { Process(items []any) error } func Pipe(p Producer, c Consumer) error { // TODO }

213

Bog'lanishlarni teskari aylantirish prinsipi va nima uchun foydalanish holatidan to'g'ridan-to'g'ri depo metodlarini chaqirish SOLID prinsipini buzadi.

212

Ma'lumotlar bazalari haqida gapir — qaysi biri bilan ishlagan va hozirda qaysi biri bilan ishlayapsan?

212

Local, dev, stage, prod muhitlari qanday farq qiladi?

211

Siz qanday qilib bajarilgan so'rovlarning to'g'riligi tekshiruvi va sinovini o'tkazdingiz?

Junior — Middle
211

/* Mikroservis arxitekturaga ega bo'lgan ilova mavjud. Mikroservis Backend interfeysi yordamida abstraktsiya qilinishi mumkin. Bir mikroservis nusxasiga kirish uchun BackendImpl turidan foydalanish mumkin, u allaqachon amalga oshirilgan. Har bir mikroservisda bir necha o'nlab ishga tushirilgan nusxalar mavjud, ularning har biri o'z manzili addr orqali kirish mumkin. Ammo, mikroservisning alohida nusxalari ishonchli emas: ular yiqilishi, mavjud bo'lmasligi yoki ortiqcha yuklangan bo'lishi mumkin. Shuning uchun, siz Balancer turini amalga oshirishingiz kerak, u ham Backend interfeysini amalga oshiradi va mikroservis nusxalari o'rtasida mijoz tomonidagi yukni tenglashtirishni amalga oshiradi, har safar **eng kam yuklangan** nusxani tanlab. */

210

JWT o'zining haqiqiyligini qanday tekshiradi? Token soxta emasligini qanday tasdiqlaydi?

210

/* Mikroservis arxitekturasi bilan ilova mavjud. Mikroservis Backend interfeysi yordamida abstraktsiya qilinishi mumkin. Mikroservisning bir nusxasiga kirish uchun, allaqachon amalga oshirilgan BackendImpl turidan foydalanishingiz mumkin. Har bir mikroservisda bir necha o'nlab ishga tushirilgan nusxalar mavjud, ularning har biri o'z manzili addr bilan kirish mumkin. Biroq, mikroservisning alohida nusxalari ishonchli emas: ular yiqilishi, kirish imkoniyati bo'lmasligi yoki ortiqcha yuklangan bo'lishi mumkin. Shuning uchun, siz klient tomonidagi yukni muvozanatlash uchun Balancer turini amalga oshirishingiz kerak, u ham Backend interfeysini amalga oshiradi va har safar **eng kam yuklangan** nusxani tanlaydi. */ type Request interface{} type Response interface{} type Backend interface { Invoke(ctx context.Context, req Request) (Response, error) } var _ Backend = &BackendImpl{} // addr, muayyan nusxaning ip:port manzili func NewBackend(addr string) *BackendImpl type Balancer struct { // TODO } var _ Backend = &Balancer{} // addrs, yuk muvozanatlashadigan barcha nusxalarning manzillarini o'z ichiga oladi func NewBalancer(addrs []string) *Balancer { // TODO }

209

Paralel so'rovlarni cheklash uchun yechim sifatida semafor va bufferli kanalning cheklovlari nima?

208

Oyna to'g'ri bo'lsa, javobga nima qo'shiladi?

207

Xarita elementlarini qanday solishtirish mumkin? Ikki xarita mos keladimi yoki yo'qligini qanday tekshirish mumkin?

205

Eng yuqori yuklangan xizmat qanday maksimal so'rovlar sonini (RPS) qayta ishlagan?

204

Go tilida vazifa yozing — amaliy bo'lim (dasturchining hayotidan muammolar, algoritmsiz): xizmatni takomillashtirish yoki tuzatish. Davomiyligi — 1,5 soat.

204

Ish formatlari: masofaviy, ofisda yoki gibrid?

203

Qanday qilib xotirani doimiy qilish mumkin (unikal belgilar soniga bog'liqlikni olib tashlash)?

203
/11