Mohol by ste uviesť svoju aktuálnu úroveň príjmu?
Golang
Povedajte nám o najťažšej a najzaujímavejšej úlohe, ktorú ste riešili, najmä o architektonických skúsenostiach.
Žiješ momentálne v Moskve? Aké mesto zvažuješ? Zvažuješ hybridný formát práce? V akej fáze hľadania sa nachádzaš?
Máte iné aktívne procesy pohovorov?
Ako sa tieto metrike integrujú a zobrazujú v Grafana?
Aký bol zloženie tímu, s ktorým ste naposledy pracovali?
Navrhnite škálovateľný systém na odosielanie správ, ktorý podporuje 150 miliónov používateľov, 75 miliónov DAU, 225 miliónov MAU, 1.2M čítaní / 300k zápisov QPS, 5 miliónov súčasných používateľov, 60 PB nových dát ročne, rast 30% ročne, P99 <200 ms pre čítanie, <300 ms pre zápis, SLA 99.95%. KONTEXT Je potrebné navrhnúť distribuovaný systém na odosielanie správ, podobný WhatsApp, ktorý podporuje 1:1 a skupinové chaty, zabezpečuje doručenie správ, zobrazuje online stavy používateľov a prenáša multimediálne súbory (fotky, videá, audio). Systém musí zabezpečiť vysokú dostupnosť a nízku latenciu, zvládať vysoký paralelizmus a byť škálovateľný na globálnej úrovni. FUNKČNÉ POŽIADAVKY - Podpora osobných (1:1) a skupinových chatov s možnosťou pridania/odstránenia účastníkov - Odosielanie a prijímanie textových správ a multimediálnych súborov Nefunkčné požiadavky: - Nie je jasná implementácia mechanizmu end-to-end šifrovania na úrovni služieb alebo klientov, okrem všeobecnej poznámky. - Chýba jasný opis sharding a replikácie databáz podľa chat_id alebo user_id pre škálovateľnosť a odolnosť voči chybám. - Nie je jasný žiadny komponent alebo mechanizmus pre offline synchronizáciu správ a potvrdení doručenia. - Nie je jasné, ako sa vykonáva vyvažovanie záťaže medzi databázami a službami, najmä pri špičkách. **Kritické body na zváženie:** (Diagrama ukazuje architektúru s Load Balancer, API Gateway, Message Queue, Service, Cache, Database, Object Storage a CDN.)
máš aktívny GitHub alebo LinkedIn?
Povedz stručne, čím si sa zaoberal na predchádzajúcich pracoviskách a aké funkcie si implementoval.
Dizajn skalovateľného systému správ, ktorý podporuje 150 miliónov používateľov, 75 miliónov DAU, 225 miliónov MAU, 1,2 milióna peak QPS čítania / 300k zápisov, 5 miliónov súčasných používateľov, 60 PB nových dát ročne, rast o 30 % ročne, SLA 99,95 %, p99 <200 ms pre čítanie, <300 ms pre zápis. KONTEXT Je potrebné navrhnúť distribuovaný systém správ, podobný WhatsApp, ktorý podporuje 1:1 a skupinové chaty, zabezpečuje doručovanie správ, zobrazuje online stavy používateľov a umožňuje prenos multimediálnych súborov (fotky, videá, audio). Systém musí zabezpečiť vysokú dostupnosť a nízku latenciu, podporovať vysoký paralelizmus a škálovať na globálnej úrovni. POŽIADAVKY NA FUNKCIE - Podpora osobných (1:1) a skupinových chatov s možnosťou pridávať/odstraňovať účastníkov - Odosielanie a prijímanie textových správ a multimediálnych súborov Nie je jasná implementácia end-to-end šifrovania na úrovni služieb alebo klientov, okrem všeobecnej poznámky. - Chýba jasný opis sharding a replikácie databáz podľa chat_id alebo user_id pre škálovateľnosť a odolnosť voči chybám. - Nie je jasný komponent alebo mechanizmus pre offline synchronizáciu správ a potvrdení doručenia. - Nie je jasné, ako sa vykonáva vyvažovanie záťaže medzi databázami a službami, najmä pri špičkových zaťaženiach. **Kritické body na zváženie:**
Ako sú testy v tíme usporiadané — kto čo píše, aké pokrytie, je E2E?
/* Musíme preniesť údaje zo zdroja k spotrebiteľovi. Zdroj poskytuje údaje v malých dávkach (~desať záznamov), zatiaľ čo spotrebiteľ efektívnejšie pracuje s väčšími dávkami (~tisíc záznamov). Reálny príklad je prenos údajov z front typu Kafka do databázy Clickhouse. Zdroj: - Takmer nekonečný. - Zdroj nikdy nevráti viac ako MaxItems záznamov v jednom volaní Next. - V rámci jednej "relácie" (jedno volanie funkcie Pipe) zdroj pri každom Next vracia nové údaje. - Po reštarte však zdroj začína od predchádzajúcej "potvrdenej" pozície, označenej cookie. Preto, každá hodnota cookie, vrátená od Next, po uložené údajoch do príjemcu, musí byť potvrdená volaním na Commit, v rovnakom poradí, v akom boli vrátené od Next. Prijímateľ: - Nedokáže spracovať viac ako MaxItems naraz. Základná úroveň: Je potrebné implementovať funkciu func Pipe(p Producer, c Consumer) error, ktorá číta údaje zo zdroja, ich zoskupuje do bufferu veľkosti nie väčšej ako MaxItems a ich ukladá do príjemcu, po čom potvrdzuje pokrok v zdroji. Zložitosť: Metódy Next, Process a Commit sú spojené s sieťovými volaniami a môžu trvať dosť dlho. Na zrýchlenie procesu je potrebné paralelizovať procesy čítania, zápisu a potvrdenia pokroku. Tak, aby počas Process alebo Commit pokračovalo čítanie zo zdroja a tvorba nového bufferu. */ const MaxItems = 9999 type Producer interface { // Next vráti: // - dávku položiek na spracovanie // - cookie na potvrdenie, keď je spracovanie dokončené // - chybu Next() (items []any, cookie int, err error) // Commit sa používa na označenie dávky dát ako spracovaných Commit(cookie int) error } type Consumer interface { Process(items []any) error } func Pipe(p Producer, c Consumer) error { // TODO }
Ako zvýšiť efektívnosť vyhľadávania prvkov v dátovej štruktúre Map?
/* PostgreSQL-ové dva serveri: * PROD - OLTP server, * STATS - server pre dlhých analytických dopytov. Na aktuálnom serveri, v databáze prod, je veľká tabuľka (10Tb) s nasledujúcou štruktúrou: CREATE TABLE profiles( id SERIAL, data JSONB ) V tabuľke môžu byť "dierky", t.j. niektoré `id` môžu byť vynechané. Je potrebné napísať program na kopírovanie tabuľky profiles z PROD na STATS. Predpokladá sa, že sa budú používať nasledujúce rozhrania na prácu s databázami: type Row []interface{} type Database interface { // implementácia rozhrania Database môže znovu nadviazať spojenia // volanie 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 // Ak je full=false, pokračovať v prenose dát od miesta predchádzajúcej chyby // Ak je full=true, preniesť všetky dáta func CopyTable(fromName string, toName string, full bool) error { // ... váš kód } Ak je zadaná voľba `full=false`, program by mal pokračovať v prenose dát od miesta predchádzajúcej chyby. Ak je `full=true`, mal by preniesť všetky dáta. **Základná úroveň**: - sekvenčný prenos dát v jednom toku - zotavenie po chybe (voľba `full=false`) Dodatočné informácie: - ak je potrebné, môžete rozšíriť rozhranie pridaním vlastných metód - ak je potrebné, môžete priamo použiť balík **database/sql**
/* Dodaný je reťazec znakov. Nájdite počet párov indexov i a j (i <= j), medzi ktorými nie sú opakujúce sa znaky. Pre reťazec "aba" je odpoveď 5: môžu to byť nielen ASCII [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") */
Aký je problém s aktuálnou implementáciou aktualizácie mapy v pracovníkovi (tasksRes[t.id][task{...}])?
Vysvetlite princíp invertovania závislostí a prečo priame volanie metód repozitára z prípadu použitia porušuje SOLID.
Daný je reťazec znakov. Nájdite počet párov indexov i a j (i <= j), medzi ktorými, vrátane, nie sú opakujúce sa znaky. Pre reťazec "aba" je odpoveď 5: [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") Pre reťazec "abcb" je odpoveď ?: aba 3 + 2 = 5 abcb 4 (a, b, c, d) + 1 (ab) + 1 (bc) + 1 (cb) + 1 (abc) = 8
/* Existuje aplikácia s architektúrou mikroservisov. Mikroservis môže byť abstraktný pomocou rozhrania Backend. Na prístup k inštancii mikroservisu môžete použiť typ BackendImpl, ktorý je už implementovaný. Každý mikroservis má niekoľko desiatok bežiacich inštancií, z ktorých každá je dostupná na svojej adrese addr. Avšak jednotlivé inštancie mikroservisu nie sú spoľahlivé: môžu zlyhať, byť nedostupné alebo preťažené. Preto musíte implementovať typ Balancer, ktorý tiež implementuje rozhranie Backend a vykonáva vyvažovanie záťaže na strane klienta medzi inštanciami mikroservisu, pričom vždy vyberá **najmenej zaťaženú** inštanciu. */ 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étnej inštancie func NewBackend(addr string) *BackendImpl type Balancer struct { // TODO } var _ Backend = &Balancer{} // addrs obsahujú adresy všetkých vyvážených inštancií func NewBalancer(addrs []string) *Balancer { // TODO }
Ako funguje WebSocket spojenie v architektúre — kedy sa vytvára a kto s kým komunikuje?