aidoc.uz

5-qism · Senior daraja·14-bob

Tizim dizayni va Senior darajasidagi intervyu strategiyasi

Ochiq tizim dizayni savollariga qanday yondashish kerak — uchta to'liq ishlab chiqilgan misol bilan — va Senior Flutter intervyularida so'raladigan xulq-atvor savollariga ishonchli, aniq javob berish strategiyasi.

Bu kitobning oxirgi va eng "Senior" bobi. Oldingi boblar aniq savollarga aniq javob berishga tayyorladi — "const konstruktor nima uchun kerak", "Isolate qachon ishlatiladi". Senior darajadagi intervyularda esa ko'pincha butunlay boshqa turdagi savol keladi: "Instagram Stories'ga o'xshash funksiyani qanday loyihalar edingiz?" Bu yerda to'g'ri javob yo'q — baholanadigan narsa sizning fikrlash jarayoningiz: talablarni qanday aniqlaysiz, murakkablikni qanday bo'laklarga ajratasiz, trade-off'larni qanday asoslaysiz. Ikkinchi yarmi esa — texnik bo'lmagan, lekin xuddi shunday muhim: xulq-atvor (behavioral) savollari, ular orqali intervyuchi sizning jamoada qanday ishlashingizni baholaydi.

1. Tizim dizayni savoliga qanday yondashish kerak#

Eng katta xato — savolni eshitib, darhol kod yoki arxitektura yozishga tushib ketish. Buning o'rniga quyidagi tartibga rioya qiling:

  1. Talablarni aniqlashtiring (2-3 daqiqa)

    "Offline ishlashi kerakmi? Necha million foydalanuvchi kutilyapti? Real-vaqt yangilanish shartmi, yoki pull-to-refresh yetarlimi?" — savol qasddan noaniq beriladi. Aniqlashtiruvchi savollar bermaslik — talabalarcha yondashuv belgisi.

  2. Ma'lumotlar qatlamini loyihalang

    Qaysi ma'lumot qayerda saqlanadi: serverda, mahalliy bazada (Hive/Drift/sqflite), xotirada (in-memory cache)? Sinxronizatsiya qanday ishlaydi — qaysi tomon "haqiqat manbai" (source of truth) hisoblanadi?

  3. State management yondashuvini tanlang va asoslang

    "Bu yerda Bloc tanlayman, chunki ko'p sonli asinxron hodisa (event) bor va ularni test qilish oson bo'lishi kerak" — tanlovni har doim sabab bilan bog'lang, shunchaki "men Bloc'ni yaxshi bilaman" emas.

  4. Navigatsiya va ekranlar oqimini chizing

    Og'zaki: "Asosiy ekrandan detalga o'tamiz, u yerdan modal orqali tahrirlash ochiladi, chuqur havola (deep link) to'g'ridan-to'g'ri detal ekraniga olib borishi kerak."

  5. Performance va offline holatlarni ko'rib chiqing

    Katta ro'yxat qanday render qilinadi? Tarmoq uzilganda foydalanuvchi nima ko'radi? Konflikt (ikki qurilmada bir vaqtda o'zgartirilgan ma'lumot) qanday hal qilinadi?

  6. Test strategiyasini eslatib o'ting

    Qaysi qatlamlar unit, qaysilari widget/integration test bilan qamrab olinadi — bu intervyuchiga "ishlab chiqarishga tayyor" fikrlash tarzini ko'rsatadi.

2. Misol 1 — Offline-first chat ilovasi#

Talab: foydalanuvchilar xabar yuboradi, ilova internetsiz ham ochilib, oldingi xabarlarni ko'rsata olishi, tarmoq qaytganda avtomatik sinxronlanishi kerak.

Ma'lumotlar qatlami. Har bir xabar mahalliy bazaga (masalan, Drift — SQLite ustidagi type-safe qatlam) darhol yoziladi, status maydoni bilan: sending, sent, failed. UI faqat mahalliy bazani o'qiydi — server hech qachon to'g'ridan-to'g'ri UI'ga ta'sir qilmaydi. Bu naqsh "local-first" yoki "single source of truth — device" deb ataladi:

UI (StreamBuilder)
Faqat mahalliy bazadagi Stream'ni tinglaydi — hech qachon to'g'ridan-to'g'ri tarmoqqa murojaat qilmaydi
Repository
Yozish so'rovlarini darhol mahalliy bazaga saqlaydi, fonda SyncEngine'ga navbatga qo'yadi
SyncEngine (background)
Navbatdagi o'zgarishlarni serverga yuboradi, konfliktlarni hal qiladi, natijani mahalliy bazaga qaytarib yozadi

Xabar yuborish oqimi: foydalanuvchi "Yuborish" tugmasini bosadi → xabar darhol status: sending bilan mahalliy bazaga yoziladi va ekranda darhol ko'rinadi (optimistic UI) → fon jarayoni (background isolate yoki oddiy async task) serverga yuboradi → muvaffaqiyatli bo'lsa status: sentga yangilanadi, xato bo'lsa status: failedga o'tadi va foydalanuvchi qayta urinish tugmasini ko'radi.

Konflikt hal qilish: agar bir xabar ikki qurilmada (masalan, telefon va planshet) ketma-ket tahrirlansa, oddiy "so'nggi yozuv g'olib" (last-write-wins, server timestamp bo'yicha) strategiyasi ko'pchilik chat ilovalar uchun yetarli — Google Docs darajasidagi operatsion transformatsiya (OT) yoki CRDT faqat hamkorlikda bir vaqtda tahrirlash kerak bo'lganda oqlanadi, oddiy chat uchun ortiqcha murakkablik bo'lardi.

State management: Bloc — chunki xabar holatlari (sending/sent/failed/ received) aniq, cheklangan hodisalar to'plami sifatida modellashtiriladi va buni unit test bilan to'liq qamrab olish oson.

3. Misol 2 — E-commerce mahsulot ro'yxati (pagination + caching)#

Talab: minglab mahsulot, sekin tarmoqda ham tez ochilishi, oldingi ko'rilgan sahifa keshdan darhol ko'rsatilishi kerak.

Yondashuv — "cache-then-network" naqshi:

  1. Ekran ochilganda avval mahalliy keshdagi (agar bor bo'lsa) so'nggi natija darhol ko'rsatiladi — foydalanuvchi bo'sh ekran ko'rmaydi.
  2. Fonda serverdan yangi ma'lumot so'raladi; kelganda ro'yxat almashtiriladi (odatda sezilmas tarzda, agar farq katta bo'lmasa).
  3. ListView.builder + sahifalash kontrolleri: ro'yxat oxiriga 200-300px qolganda keyingi sahifa avtomatik so'raladi (ScrollController.addListener).
class ProductListCubit extends Cubit<ProductListState> {
  ProductListCubit(this._repo) : super(ProductListState.initial());
  final ProductRepository _repo;
  bool _isFetching = false;
 
  Future<void> loadNextPage() async {
    if (_isFetching || state.hasReachedEnd) return;
    _isFetching = true;
    try {
      final nextPage = await _repo.fetchProducts(page: state.page + 1);
      emit(state.copyWith(
        items: [...state.items, ...nextPage.items],
        page: state.page + 1,
        hasReachedEnd: nextPage.items.isEmpty,
      ));
    } finally {
      _isFetching = false;
    }
  }
}

Nega bu yechim to'g'ri: _isFetching flag'i bir vaqtning o'zida bir nechta sahifa so'rovini (masalan, foydalanuvchi tez scroll qilganda) oldini oladi — bu ko'pincha intervyuda unutiladigan, lekin production'da darhol sezilib qoladigan detal. Rasmlar uchun cached_network_image kabi kutubxona — disk keshini avtomatik boshqaradi, shu bilan har safar qayta yuklab olishning oldi olinadi.

Performance: har bir mahsulot karta widget'i const bo'lishi mumkin bo'lgan qismlarni ajratadi (masalan, statik ikon), rasm o'lchamlari serverdan kerakli o'lchamda (thumbnail) so'raladi — to'liq o'lchamli rasmni yuklab, uni UI'da kichraytirish xotira va tarmoqni behuda sarflaydi.

4. Misol 3 — Video-streaming pleer holati#

Talab: video ijro etish, sifat almashtirish, orqa fonda ijro (audio-only), tarmoq uzilganda avtomatik pauza va qayta ulanishda davom ettirish.

Bu yerdagi asosiy qiyinchilik — pleer holati juda ko'p manbadan kelishi: foydalanuvchi amali (play/pause tugmasi), tizim hodisasi (qo'ng'iroq kelishi, headphone uzilishi), tarmoq holati, va video kodekning o'z ichki holati (buferlash, xato). Bularning barchasini bitta cheklangan holatlar mashinasi (finite state machine) sifatida modellashtirish kerak:

sealed class PlayerState {}
class PlayerIdle extends PlayerState {}
class PlayerBuffering extends PlayerState {}
class PlayerPlaying extends PlayerState {}
class PlayerPaused extends PlayerState {
  PlayerPaused(this.reason);
  final PauseReason reason; // user, systemInterruption, networkLoss
}
class PlayerError extends PlayerState {
  PlayerError(this.message);
  final String message;
}

Dart 3'ning sealed class + switch exhaustiveness tekshiruvi bu yerda juda qo'l keladi — yangi holat qo'shilsa, kompilyator uni qayta ishlamagan barcha joylarni xato deb belgilaydi, ya'ni "unutilgan holat" ishlab chiqarishga chiqib ketmaydi.

Trade-off suhbati (buni intervyuda aytish muhim): orqa fonda audio ijro etishni qo'llab-quvvatlash uchun native platform integratsiyasi (Android MediaSession, iOS AVAudioSession + Background Modes) kerak bo'ladi — bu sof Dart bilan yechilmaydi, platform kanal orqali native kod yozishga to'g'ri keladi (12-bobda ko'rilgan). Buni oldindan aytish — real loyihalarda duch kelinadigan chegaralarni bilishni ko'rsatadi.

5. Intervyu strategiyasi va xulq-atvor savollari#

Texnik bilim Senior lavozim uchun zarur, lekin yetarli emas. Intervyuchilar ko'pincha xuddi shu darajada — sizning qanday fikr yuritishingiz, qanday qaror qabul qilishingiz va jamoada qanday ishlashingizni baholashadi. Bu bo'limdagi savollarga tayyorgarlik ko'rishning eng yaxshi usuli — o'z real loyihalaringizdan 3-4 ta aniq voqeani oldindan tayyorlab qo'yish (STAR usuli: Situation, Task, Action, Result), umumiy "biz doim yaxshi ishladik" degan javoblardan qochish.

Tez-tez so'raladigan intervyu savollari#

Savol: Instagram Stories'ga o'xshash funksiyani qanday loyihalagan bo'lardingiz?

Javob: Avval talablarni aniqlashtiraman: stories 24 soatdan keyin o'chadimi, offline holda ko'rish kerakmi, kim ko'rganini kuzatish kerakmi. Ma'lumotlar qatlamida har bir story — media URL + TTL (time-to-live) bilan saqlanadi, mahalliy keshda oldindan yuklab olinadi (prefetching) — foydalanuvchi keyingi story'ga o'tganda kutish bo'lmasligi uchun. UI'da PageView + custom progress indikatorlar, media pleer holati (yuklanmoqda/ijro/pauza) alohida state sifatida boshqariladi. Xotira boshqaruvi muhim — bir vaqtning o'zida faqat joriy va keyingi 1-2 ta media xotirada saqlanadi, qolganlari disk keshida.

Savol: Katta jamoada ishlaydigan real-vaqt hamkorlik (masalan, Google Docs'ga o'xshash) funksiyani qanday loyihalar edingiz?

Javob: Bu yerda asosiy murakkablik — bir vaqtda tahrirlash konfliktlari. Oddiy "last-write-wins" yetarli emas, chunki matn butunlay yo'qolishi mumkin. CRDT (Conflict-free Replicated Data Type) yoki operatsion transformatsiya (OT) kerak bo'ladi — bu odatda mavjud kutubxona (masalan, Yjs'ning Dart porti yoki backend'da amalga oshirilgan OT serveri) orqali yechiladi, o'zimiz noldan yozmagan bo'lardik, chunki bu juda murakkab va xato-sezgir soha. Flutter tomonida vazifa — WebSocket orqali kelayotgan delta'larni tez va to'g'ri render qilish, tarmoq uzilganda mahalliy o'zgarishlarni navbatga qo'yib turish.

Savol: Arxitektura qarorini texnik bo'lmagan manager'ga qanday tushuntirasiz?

Javob: Metafora va natija-yo'naltirilgan tilni ishlataman, texnik jargon'siz. Masalan, Riverpod'ga o'tishni tushuntirganda "kod ichidagi tekshirish tizimini kuchaytiramiz — bu ilovada xatolar kamayishiga va yangi funksiyalarni tezroq qo'shishga olib keladi" deyman, "compile-time safety" yoki "dependency injection" kabi so'zlarni ishlatmayman. Har doim nima uchun bu ularga muhim ekanini (tezlik, sifat, xarajat) birinchi o'ringa qo'yaman, qanday ekanini emas.

Savol: Code review qilishda qanday tamoyillarga amal qilasiz?

Javob: Uchta narsani tekshiraman: to'g'rilik (kod aytilganini qiladimi), saqlanuvchanlik (olti oydan keyin boshqa kishi tushunadimi) va izchillik (loyihaning mavjud naqshlariga mos keladimi). Kichik uslub masalalarida (masalan, o'zgaruvchi nomi) qat'iy talab qilmayman, agar avtomatik formatlash/ lint bilan hal qilinmasa. Muhim arxitektura muammosini topsam, "buni o'zgartiring" emas, "bu yerda X sabab bo'lishi mumkin, Y variantini ko'rib chiqdingizmi?" deb savol shaklida yozaman — bu muhokamani ochiq qoldiradi va muallifni himoyaga o'tishga majburlamaydi.

Savol: O'tgan loyihada qilgan texnik xatoingiz haqida gapirib bering.

Javob: Bir loyihada GlobalKeylarni ro'yxat elementlarida (har bir item uchun alohida key) keng qo'lladim, chunki animatsiya uchun kerak deb o'yladim. Ro'yxat 500+ elementga yetganda ilova sezilarli sekinlasha boshladi — GlobalKeylar har birini butun ilova bo'ylab noyob elementga bog'laydi va Flutter ularni maxsus, qimmatroq mexanizm bilan kuzatadi. Muammoni DevTools profayllovchisi (profiler) bilan topdim, keyin faqat haqiqatan ham kerak bo'lgan 2-3 ta widget'da GlobalKey qoldirib, qolganlarida oddiy ValueKeyga o'tkazdim — render vaqti sezilarli qisqardi. O'shandan beri "GlobalKey — oxirgi chora, birinchi tanlov emas" degan qoidaga amal qilaman.

Savol: Nega o'tgan loyihangizda Riverpod'ni Bloc o'rniga tanladingiz (yoki aksincha)?

Javob: Bu jamoa tarkibiga va loyiha xususiyatiga bog'liq bo'lgan qaror edi. Kichik, tez o'zgaruvchan jamoada Riverpod'ni tanladim, chunki u boilerplate'ni kamaytiradi va yangi dasturchilar uchun kirish bo'sag'asi pastroq. Boshqa loyihada, ko'plab asinxron hodisalarni aniq test qilish talab qilinganda, Bloc'ning event-state modeli va uning test infratuzilmasi (bloc_test) afzal bo'ldi. Men "eng yaxshi kutubxona" degan yagona javobga ishonmayman — bu doim kontekstga bog'liq, va buni intervyuda ham shunday aytaman.

Savol: Jamoada tajribasi kam dasturchiga qanday mentorlik qilasiz?

Javob: Avval to'g'ridan-to'g'ri yechimni bermayman — "sen bu yerda qanday fikrlaysan?" deb so'rab, ularning fikrlash jarayonini ko'raman. Agar tiqilib qolishsa, to'liq javob emas, keyingi qadam uchun yo'nalish beraman. Kod review'da nafaqat "nima noto'g'ri", balki "nega bu yondashuv muammoli"ni tushuntiraman — maqsad faqat shu PR'ni tuzatish emas, keyingi safar o'zlari buni oldindan ko'ra olishlari.

Savol: Muddat siqilib qolganda sifatni qanday saqlaysiz?

Javob: Avval nimani qurbon qilish mumkinligini aniq belgilayman — masalan, test qamrovi vaqtinchalik pasayishi mumkin, lekin xavfsizlik va ma'lumotlar yaxlitligi bilan bog'liq kod hech qachon qurbon qilinmaydi. Texnik qarz (technical debt) qoldirilsa, buni jamoaga ochiq aytaman va keyingi sprintga aniq topshiriq sifatida yozib qo'yaman — "keyin tuzatamiz" degan noaniq va'da emas.

Savol: Nima uchun aynan bizning kompaniyaga, aynan shu lavozimga qiziqasiz? (Bu savolni tugatishdan oldin so'rang)

Javob: Bu yerda umumiy javob ("ilg'or texnologiyalar" kabi) o'rniga kompaniyaning aniq mahsuloti/muammosi bilan bog'liq, real qiziqishingizni ko'rsatish kerak — masalan, "sizning ilovangiz offline-first yondashuvni qanday hal qilgani meni qiziqtirdi, chunki men aynan shu muammo ustida ishlaganman va sizning yechimingizdan o'rganmoqchiman." Suhbat oxirida intervyuchiga savol berish ham muhim: "jamoada texnik qarorlar qanday qabul qilinadi?" yoki "eng katta arxitektura muammosi hozir nima?" kabi savollar — bu ham qiziqishni, ham senior darajadagi fikrlashni ko'rsatadi.

Ko'p uchraydigan xato javoblar#

VaziyatXato yondashuvTo'g'ri yondashuv
Tizim dizayni savoli berilgandaDarhol kod yoki aniq arxitektura yozishga tushishAvval talablarni aniqlashtirish, keyin bosqichma-bosqich fikrlash
"Nega bu kutubxonani tanladingiz?""Chunki men uni yaxshi bilaman"Loyiha talablari va trade-off'lar asosida asoslash
Xato haqida so'ralganda"Men hech qachon jiddiy xato qilmaganman"Aniq, real voqea + undan nima o'rganilgani (bu ishonchni oshiradi, kamaytirmaydi)
Intervyu oxirida savol so'ralganda"Yo'q, savolim yo'q"Jamoa, arxitektura yoki texnik qarorlar haqida mazmunli savol berish
Trade-off haqida so'ralgandaFaqat bitta yechimni "eng yaxshi" deb ko'rsatishKamida ikkita variantni solishtirib, nega aynan shu tanlangani aniq asoslash
Amaliy topshiriq

O'z 'katta uchlik' voqealaringizni tayyorlang

Real ish tajribangizdan (yoki shaxsiy loyihalaringizdan) uchta aniq voqeani yozma ravishda tayyorlang, har birini 30 soniyada og'zaki aytib bera oladigan darajada qisqartiring. Bu bobdagi savollarning aksariyati shu uchta voqeadan biriga moslashtirilishi mumkin.

Maslahatni ko'rsatish

STAR usulida (Situation, Task, Action, Result) yozing: (1) qiyin texnik qaror qabul qilgan voqea, (2) jiddiy xatoni tuzatgan voqea, (3) boshqa dasturchiga yordam bergan voqea.