Sobes.tech

Golang

Hazırda Moskva şəhərində yaşayırsan? Hansı şəhəri nəzərdən keçirirsən? Hibrid iş formatını düşünürsən? Axtarışın hansı mərhələsindəsən?

223

Başqa aktiv müsahibə prosesləriniz varmı?

222

Bu metrik məlumatlar Grafana-da necə inteqrasiya olunur və göstərilir?

Junior — Middle
221

Hazırkı gəlir səviyyənizi qeyd edə bilərsinizmi?

Junior — Middle
221

150 milyon istifadəçiyə dəstək verən, 75 milyon DAU, 225 milyon MAU, 1.2M oxuma / 300k yazma QPS, 5 milyon eyni vaxtda istifadəçi, ildə 60 PB yeni məlumat, illik 30% artım, P99 <200 ms oxuma üçün, <300 ms yazma üçün, SLA 99.95% dəstəkləyən miqyaslana bilən mesajlaşma sistemi layihələndirin. KONTEXT WhatsApp-ə bənzər, mesajların çatdırılmasını təmin edən, istifadəçilərin onlayn statuslarını göstərən və multimedia fayllarını (şəkil, video, audio) ötürən paylanmış mesajlaşma sistemi layihələndirmək lazımdır. Sistem yüksək əlçatanlıq və aşağı gecikmə təmin etməli, yüksək paralelliyi dəstəkləməli və qlobal miqyasda genişlənə bilməlidir. FUNKSİONAL TƏLƏBLƏR - 1:1 və qrup söhbətləri dəstəyi, iştirakçıların əlavə və ya çıxarılması imkanı ilə - Mətn mesajlarının və multimedia fayllarının göndərilməsi və alınması Qeyri-funksional tələblər: - Servis və ya müştərilərdə end-to-end şifrələmə mexanizminin açıq tətbiqi yoxdur, ümumi qeyd ilə xaric. - chat_id və ya user_id əsasında verilənlər bazalarının sharding və replikasiyasının açıq şəkildə təsviri yoxdur, miqyaslana bilənlik və uğursuzluğa davamlılıq üçün. - Offline mesajların sinxronizasiyası və çatdırılma hesabatları üçün açıq komponent və ya mexanizm yoxdur. - Yük balanslaşdırmanın verilənlər bazaları və xidmətlər arasında, xüsusən pik vaxtlarda necə həyata keçirildiyi aydın deyil. **Diqqət yetirilməli olan nöqtələr:** (Diagramda Load Balancer, API Gateway, Message Queue, Service, Cache, Database, Object Storage və CDN ilə arxitektura göstərilir.)

220

Sonuncu dəfə işlədiyiniz komandanın tərkibi necə idi?

Junior — Middle
219

İşə yarayan GitHub və ya LinkedIn-in varmı?

218

Məlumatların oxunması zamanı saniyədə əməliyyatların sayı göstəricisi olaraq nə səviyyəyə çatdınız və ya analiz etdiniz?

Middle — Middle+
218

Əvvəlki iş yerlərində nə ilə məşğul olduğunuzu və hansı xüsusiyyətləri həyata keçirdiyinizi qısa şəkildə izah edin.

214

/* Biz müəyyən bir mənbədən müəyyən bir istehlakçıya məlumat ötürməliyik. Mənbə kiçik partiyalar (~on qeyd) şəklində məlumat verir, halbuki, istehlakçı böyük partiyalar (~minlərlə qeyd) ilə daha səmərəli işləyir. Həqiqi nümunə Kafka tipli növbələrdən məlumatların Clickhouse bazasına ötürülməsidir. Mənbə: - Demək olar ki, sonsuz. - Mənbə heç vaxt Next çağırışında MaxItems-dən çox qeyd qaytarmır. - Bir "sessiya" (bir Pipe funksiyasının çağırışı) çərçivəsində, mənbə hər Next çağırışında yeni məlumatlar qaytarır. - Ancaq, yenidən başlatdıqdan sonra, mənbə əvvəlki "təsdiqlənmiş" mövqedən, cookie ilə göstərilən yerdən başlayır. Buna görə, Next tərəfindən qaytarılan hər cookie dəyəri, məlumatlar qəbul ediciyə saxlandıqdan sonra, Commit çağırışı ilə təsdiqlənməlidir, və yaşıdları ilə eyni ardıcıllıqda. Qəbul edən: - Eyni zamanda MaxItems-dən çox işləyə bilməz. Əsas səviyyə: func Pipe(p Producer, c Consumer) error funksiyasını həyata keçirmək lazımdır, bu mənbədən məlumat oxuyur, onları MaxItems-dən çox olmayan bufferdə qruplaşdırır və qəbulçiyə saxlayır, sonra isə mənbədə irəliləyişi təsdiqləyir. Çətinlik: Next, Process və Commit metodları şəbəkə çağırışları ilə əlaqəlidir və çox vaxt ala bilər. Prosesin sürətini artırmaq üçün, oxuma, yazma və irəliləyişi təsdiqləmə proseslərini paralel həyata keçirmək lazımdır. Belə ki, Process və ya Commit çağırışları zamanı, mənbədən oxuma və yeni bufferin formalaşması davam etsin. */ const MaxItems = 9999 type Producer interface { // Next aşağıdakıları qaytarır: // - işlənəcək elementlər partiyası // - təsdiqləmə üçün cookie // - xəta Next() (items []any, cookie int, err error) // Commit, məlumat partiyasını işlənmiş kimi işarələmək üçün istifadə olunur Commit(cookie int) error } type Consumer interface { Process(items []any) error } func Pipe(p Producer, c Consumer) error { // TODO }

213

/* Verilmiş simvol sətiri. Təkrarlanmayan simvollar arasında i və j indeksləri cütlərinin sayını tapın. "aba" sətiri üçün cavab 5: yalnız ASCII olmaya bilər [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") */

211

Komanda daxilində testlər necə qurulub — kim nə yazır, hansı əhatə, E2E varmı?

210

Verilən bir simvol sətiri. İ və j indekslərinin cütlüyünü tapın (i <= j), onların arasında, daxil olmaqla, təkrarlanan simvollar yoxdur. "aba" sətiri üçün cavab 5: [0, 0] ("a") [0, 1] ("ab") [1, 1] ("b") [1, 2] ("ba") [2, 2] ("a") "abcb" sətiri üçün cavab ?: aba 3 + 2 = 5 abcb 4 (a, b, c, d) + 1 (ab) + 1 (bc) + 1 (cb) + 1 (abc) = 8

209

/* Mikroservis memarizası ilə tətbiq mövcuddur. Mikroservis Backend interfeysi vasitəsilə abstraktlaşdırıla bilər. Mikroservisin bir nümunəsinə giriş üçün, artıq tətbiq olunmuş BackendImpl tipindən istifadə edə bilərsiniz. Hər mikroservisin bir neçə onlarla işləyən nümunəsi var, hər biri öz ünvanı addr ilə əlçatan. Ancaq, mikroservisin ayrı-ayrı nümunələri etibarlı deyil: onlar çökmə, əlçatan olmama və ya yüklənmə ilə qarşılaşa bilər. Buna görə, siz müştəri tərəfi yük balanslaşdırması həyata keçirən və hər dəfə **ən az yüklənmiş** nümunəni seçən Balancer tipini tətbiq etməlisiniz. */ type Request interface{} type Response interface{} type Backend interface { Invoke(ctx context.Context, req Request) (Response, error) } var _ Backend = &BackendImpl{} // addr müəyyən nümunənin ip:port ünvanını ehtiva edir func NewBackend(addr string) *BackendImpl type Balancer struct { // TODO } var _ Backend = &Balancer{} // addrs bütün balanslaşdırılan nümunələrin ünvanlarını ehtiva edir func NewBalancer(addrs []string) *Balancer { // TODO }

209

Arxitekturada WebSocket əlaqəsi necə işləyir — hansı vaxtda qurulur və kim kimlə əlaqə saxlayır?

209

Komanda idarəetmə təcrübəniz varmı?

208

150 milyon istifadəçini dəstəkləyən, 75 milyon DAU, 225 milyon MAU, 1.2M oxuma / 300k yazma zirvəsi QPS, 5 milyon eyni vaxtda istifadəçi, ildə 60 PB yeni məlumat, illik 30% artım, SLA 99.95%, p99 <200 ms oxumaq üçün, <300 ms yazmaq üçün, miqyaslana bilən mesajlaşma sistemi layihələndirmək. KONTEKST WhatsApp-ə bənzər, 1:1 və qrup söhbətlərini dəstəkləyən, mesajların çatdırılmasını təmin edən, istifadəçilərin onlayn statuslarını göstərən və multimedia fayllarını (foto, video, audio) ötürən paylanmış mesajlaşma sistemi layihələndirmək lazımdır. Sistem yüksək mövcudluğu və aşağı gecikməni təmin etməli, yüksək paralelliyi dəstəkləməli və qlobal miqyasda genişlənə bilməlidir. FUNKSİONAL TƏLƏBLƏR - Şəxsi (1:1) və qrup söhbətlərini dəstəkləmək, iştirakçıların əlavə və ya çıxarılması imkanı ilə - Mətn mesajları və multimedia fayllarını göndərmək və qəbul etmək Xidmətlər və ya müştərilər səviyyəsində end-to-end şifrələmə mexanizminin aydın tətbiqi görünmür, ümumi qeyd xaricində. - chat_id və ya user_id əsasında verilənlər bazalarının sharding və replikasiyasının aydın təsviri yoxdur, miqyaslana bilmək və nasazlığa davamlılıq üçün. - Offline mesajların və çatdırılma qəbzlərinin sinxronizasiyası üçün aydın komponent və ya mexanizm yoxdur. - Yükün paylanması və bazalar arasında, xüsusən pik vaxtlarda, necə həyata keçirildiyi aydın deyil. **Əhəmiyyətli diqqət yetirilməli nöqtələr:**

208

Map məlumat strukturu daxilində elementlərin axtarış effektivliyini necə artıra bilərik?

Junior — Middle
207

Paylanmış sistemlərlə işləmə təcrübəniz varmı?

207

/* PostgreSQL-in iki server var: * PROD - OLTP server, * STATS - uzun analitik sorğular üçün server. Hazırkı serverdə, prod bazasında, böyük (10Tb) cədvəl var: CREATE TABLE profiles( id SERIAL, data JSONB ) Cədvəldə "deliklər" ola bilər, yəni bəzi `id`lər atlanmış ola bilər. PROD-dən STATS-ə profiles cədvəlini kopyalamaq üçün proqram yazmaq lazımdır. Aşağıdakı interfeyslərdən istifadə ediləcəyini fərz edirik: type Row []interface{} type Database interface { // Database interfeysinin tətbiqi əlaqələri yenidən qura bilər // SaveRows çağırışı idempotentdir 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 // Əgər full=false, əvvəlki xətadan sonra məlumatların köçürülməsini davam et // Əgər full=true, bütün məlumatları köçür func CopyTable(fromName string, toName string, full bool) error { // ... kodunuz } Əgər `full=false` seçimi verilsə, proqram əvvəlki xətadan sonra məlumatların köçürülməsini davam etdirməlidir. Əgər `full=true` isə, bütün məlumatları köçürməlidir. **Əsas səviyyə**: - məlumatların ardıcıl köçürülməsi tək axında - səhvlərdən sonra bərpa (seçim `full=false`) Əlavə məlumatlar: - lazım olarsa, interfeysi öz metodlarınızı əlavə etməklə genişləndirə bilərsiniz - lazım olarsa, birbaşa **database/sql** paketindən istifadə edə bilərsiniz

207
/11