Sobes.tech

Golang

Žijete momentálně v Moskvě? Jaké město zvažujete? Zvažujete hybridní formát práce? V jaké fázi hledání se nacházíte?

223

Máte jiné aktivní procesy pohovorů?

222

Jak jsou tyto metriky integrovány a zobrazovány v Grafaně?

Junior — Middle
221

Mohl byste uvést svou aktuální úroveň příjmu?

Junior — Middle
221

Návrh škálovatelného systému pro zasílání zpráv, který podporuje 150 milionů uživatelů, 75 milionů DAU, 225 milionů MAU, 1,2 milionu čtení / 300 tisíc zápisů QPS, 5 milionů současných uživatelů, 60 PB nových dat ročně, růst o 30 % ročně, P99 <200 ms pro čtení, <300 ms pro zápis, SLA 99,95 %. KONTEKST Je třeba navrhnout distribuovaný systém zasílání zpráv, podobný WhatsAppu, který podporuje 1:1 a skupinové chaty, zajišťuje doručení zpráv, zobrazuje online status uživatelů a přenáší multimediální soubory (fotky, videa, audia). Systém musí zajistit vysokou dostupnost a nízkou latenci, podporovat vysoký paralelismus a škálovat na globální úrovni. FUNKČNÍ POŽADAVKY - Podpora osobních (1:1) a skupinových chatů s možností přidávat/odstraňovat účastníky - Odesílání a přijímání textových zpráv a multimediálních souborů Nefunkční požadavky: - Neexistuje explicitní implementace end-to-end šifrování na úrovni služeb nebo klientů, kromě obecné poznámky. - Není jasně popsáno sharding a replikace databází podle chat_id nebo user_id pro škálovatelnost a odolnost vůči chybám. - Neexistuje žádná explicitní komponenta nebo mechanismus pro offline synchronizaci zpráv a potvrzení doručení. - Není jasné, jak je realizováno vyvažování zátěže mezi databázemi a službami, zejména při špičkových zatíženích. **Důležité body k zvážení:** (Diagram ukazuje architekturu s Load Balancerem, API Gateway, Message Queue, Service, Cache, Database, Object Storage a CDN)

220

Jaké bylo složení týmu, se kterým jste naposledy pracoval?

Junior — Middle
219

Jaký ukazatel počtu operací za sekundu při čtení dat jste dosáhli nebo analyzovali?

Middle — Middle+
218

Pověz stručně, čím ses zabýval na předchozích místech práce a jaké funkce jsi implementoval.

214

/* Musíme přenést data ze zdroje k příjemci. Zdroj poskytuje data v malých dávkách (~deset záznamů), zatímco příjemce s nimi pracuje efektivněji ve větších dávkách (~tisíc záznamů). Reálným příkladem je přenos dat z front typu Kafka do databáze Clickhouse. Zdroj: - Téměř nekonečný. - Zdroj nikdy nevrátí více než MaxItems záznamů v jednom volání Next. - V rámci jedné "seance" (jedno volání funkce Pipe) zdroj při každém volání Next vrací nová data. - Po restartu však zdroj začne od předchozí "potvrzené" pozice, určené cookie. Proto každý cookie vrácený Next, po uložení dat do příjemce, musí být potvrzen voláním Commit, ve stejném pořadí, v jakém byla data vrácena. Příjemce: - Nedokáže zpracovat více než MaxItems najednou. Základní úroveň: Je třeba implementovat funkci func Pipe(p Producer, c Consumer) error která čte data ze zdroje, seskupuje je do bufferu o velikosti nejvýše MaxItems a ukládá je do příjemce, po čemž potvrzuje pokrok ve zdroji. Zvýšená obtížnost: Metody Next, Process a Commit jsou spojeny s síťovými voláními a mohou trvat dlouho. Pro urychlení procesu je nutné paralelizovat procesy čtení, zápisu a potvrzování pokroku. Tak, aby během Process nebo Commit pokračovalo čtení ze zdroje a tvorba nového bufferu. */ const MaxItems = 9999 type Producer interface { // Next vrací: // - dávku položek k zpracování // - cookie k potvrzení po dokončení zpracování // - chybu Next() (items []any, cookie int, err error) // Commit se používá k označení dávky dat jako zpracované Commit(cookie int) error } type Consumer interface { Process(items []any) error } func Pipe(p Producer, c Consumer) error { // TODO }

213

/* Zadaný je řetězec znaků. Najděte počet párů indexů i a j (i <= j), mezi kterými nejsou opakující se znaky. Pro řetězec "aba" je odpověď 5: mohou být nejen ASCII [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") */

211

Jak jsou testy v týmu uspořádány — kdo co píše, jaké pokrytí, je E2E?

210

Zadaný je řetězec znaků. Najděte počet párů indexů i a j (i <= j), mezi kterými, včetně, nejsou opakující se znaky. Pro řetězec "aba" je odpověď 5: [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") Pro řetězec "abcb" je odpověď ?: aba 3 + 2 = 5 abcb 4 (a, b, c, d) + 1 (ab) + 1 (bc) + 1 (cb) + 1 (abc) = 8

209

/* Existuje aplikace s architekturou mikroservisů. Mikroservis lze abstraktně reprezentovat pomocí rozhraní Backend. Pro přístup k instanci mikroservisu můžete použít typ BackendImpl, který je již implementován. Každý mikroservis má několik desítek běžících instancí, z nichž každá je dostupná na své adrese addr. Nicméně jednotlivé instance mikroservisu nejsou spolehlivé: mohou selhat, být nedostupné nebo přetížené. Proto musíte implementovat typ Balancer, který také implementuje rozhraní Backend a provádí vyvažování zátěže na straně klienta mezi instancemi mikroservisu, přičemž vybírá pokaždé **nejméně zatíženou** instanci. */ type Request interface{} type Response interface{} type Backend interface { Invoke(ctx context.Context, req Request) (Response, error) } var _ Backend = &BackendImpl{} // addr obsahuje ip:port konkrétní instance func NewBackend(addr string) *BackendImpl type Balancer struct { // TODO } var _ Backend = &Balancer{} // addrs obsahují adresy všech vyvažovaných instancí func NewBalancer(addrs []string) *Balancer { // TODO }

209

Jak funguje připojení WebSocket v architektuře — v jakém okamžiku se navazuje a kdo komunikuje s kým?

209

Měl(a) jste zkušenosti s řízením týmu?

208

Navrhněte škálovatelný systém pro zasílání zpráv, který podporuje 150 milionů uživatelů, 75 milionů DAU, 225 milionů MAU, 1,2 milionu peak QPS čtení / 300k zápisů, 5 milionů současných uživatelů, 60 PB nových dat ročně, růst o 30 % ročně, SLA 99,95 %, p99 <200 ms pro čtení, <300 ms pro zápis. KONTEKST Je třeba navrhnout distribuovaný systém zasílání zpráv, podobný WhatsApp, který podporuje 1:1 a skupinové chaty, zajišťuje doručování zpráv, zobrazuje online statusy uživatelů a umožňuje přenos multimediálních souborů (fotky, videa, audio). Systém musí zajistit vysokou dostupnost a nízkou latenci, podporovat vysoký paralelismus a škálovat na globální úrovni. POŽADAVKY NA FUNKCE - Podpora osobních (1:1) a skupinových chatů s možností přidávat/odstraňovat účastníky - Odesílání a přijímání textových zpráv a multimediálních souborů Není zřejmá jasná implementace end-to-end šifrovacího mechanismu na úrovni služeb nebo klientů, kromě obecné poznámky. - Chybí explicitní popis sharding a replikace databází podle chat_id nebo user_id pro škálovatelnost a odolnost vůči chybám. - Neexistuje jasná komponenta nebo mechanismus pro offline synchronizaci zpráv a potvrzení doručení. - Není jasné, jak je prováděno vyvažování zátěže mezi databázemi a službami, zejména při špičkových zatíženích. **Kritické body k zvážení:**

208

Jak lze zvýšit efektivitu hledání prvků ve struktuře dat Map?

Junior — Middle
207

Máte zkušenosti s distribuovanými systémy?

207

/* Existují dva servery PostgreSQL: * PROD - OLTP server, * STATS - server pro dlouhé analytické dotazy. Na aktuálním serveru, v databázi prod, je velká tabulka (10Tb) s následující strukturou: CREATE TABLE profiles( id SERIAL, data JSONB ) V tabulce mohou být "díry", tj. některá `id` mohou být vynechána. Je třeba napsat program pro kopírování tabulky profiles z PROD na STATS. Předpokládá se, že budou použity následující rozhraní pro práci s databázemi: type Row []interface{} type Database interface { // implementace rozhraní Database může znovu navázat spojení // volání SaveRows je idempotentní 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 // Pokud je full=false, pokračovat v přenosu dat od místa předchozí chyby // Pokud je full=true, přenést všechna data func CopyTable(fromName string, toName string, full bool) error { // ... váš kód } Pokud je předána volba `full=false`, program by měl pokračovat v přenosu dat od místa předchozí chyby. Pokud je `full=true`, měl by přenést všechna data. **Základní úroveň**: - sekvenční přenos dat v jednom toku - zotavení po chybě (volba `full=false`) Další informace: - pokud je potřeba, můžete rozšířit rozhraní přidáním vlastních metod - pokud je potřeba, můžete přímo použít balíček **database/sql**

207
/11