0.1-bob: Kompyuter qanday ishlaydi — CPU, RAM, disk, binary va ma'lumot saqlash
0-QISM — TAYYORGARLIK · 1-mavzu
1. Kirish va motivatsiya
Siz yozadigan har bir kod qatori — let x = 5 bo'ladimi, array.map(...) bo'ladimi yoki butun bir React ilovasi bo'ladimi — oxir-oqibat temir parchasida (kompyuterda) ishlaydi. Dasturchining ishi, aslida, mashinaga nima qilishni aytishdir. Mashinani tushunmasdan unga buyruq berish — chet tilini bilmasdan o'sha tilda she'r yozishga urinishga o'xshaydi: ba'zida tasodifan ishlaydi, lekin nega ishlaganini yoki nega buzilganini hech qachon bilmaysiz.
Ko'p odam dasturlashni "sintaksisni yodlash" deb o'ylaydi. Bu xato. Yaxshi dasturchi bilan o'rtacha dasturchini ajratadigan narsa — ular kompyuterning ichida nima sodir bo'layotganini tasavvur qila olishidir. Mana shu bob aynan o'sha tasavvurning poydevorini quradi.
Bu bobni o'qib bo'lgach, quyidagi savollarga ishonch bilan javob bera olasiz:
- Kompyuter aslida faqat 0 va 1 bilan ishlasa, qanday qilib matn, rasm, video saqlaydi?
let user = { name: "Ali" }deb yozsam, bu qayerda turadi — RAM'dami, diskdami? Ikkalasining farqi nima?- Nega dasturim ba'zida "sekin" ishlaydi yoki "xotira yetmadi" deydi?
0.1 + 0.2nega aniq0.3chiqmaydi? (Ha, bu kompyuter haqidagi savol, JavaScript haqida emas.)
Bu — butun kitobning poydevori. Keyinchalik event loop, xotira oqishi (memory leak), Big-O murakkabligi, ma'lumotlar bazasi indekslari, Buffer, performance optimizatsiya — hammasi shu yerda qo'yiladigan tushunchalarga tayanadi.
2. Nazariya — chuqur tushuntirish
2.1. Kompyuter aslida nima?
Eng sodda ta'rifda, kompyuter — ma'lumotni qabul qilib (input), uni qayta ishlab (process), natija chiqaradigan (output) mashina. Hammasi shu uch bosqichdan iborat:
INPUT PROCESS OUTPUT
┌────────┐ ┌────────────┐ ┌──────────┐
│ klaviatura│──▶│ CPU + RAM │────▶│ ekran │
│ sichqoncha│ │ (hisoblash) │ │ printer │
│ tarmoq │ └────────────┘ │ tarmoq │
└────────┘ │ └──────────┘
▼
┌──────────┐
│ DISK │ (uzoq muddatli saqlash)
└──────────┘Kalkulyator ham, telefon ham, server ham — barchasi shu sxema bo'yicha ishlaydi. Faqat tezligi, hajmi va murakkabligi farq qiladi.
2.2. Nega aynan 0 va 1? (Binary — ikkilik sanoq sistemasi)
Kompyuterning "miyasi" millionlab (zamonaviylarda milliardlab) mayda elektron kalitlardan — tranzistorlardan iborat. Tranzistor — bu juda kichik elektr kalit. Uning faqat ikkita ishonchli holati bor:
- tok bor biz buni 1 deymiz (yoniq);
- tok yo'q biz buni 0 deymiz (o'chiq).
O'xshatish: xonangizdagi chiroq kalitini tasavvur qiling. U yo yoniq, yo o'chiq. "Yarim yoniq" degan ishonchli holat yo'q — agar bo'lsa ham, uni aniq o'lchash qiyin. Tranzistor ham xuddi shunday: ikki holat orasini farqlash oson va ishonchli, shuning uchun kompyuter butun dunyoni shu ikki holat bilan ifodalaydi.
Nega 10 ta holat (bizning odatdagi sanoq sistemamizdek) emas? Chunki elektr signalida 10 ta turli kuchlanish darajasini bir-biridan ishonchli ajratish juda qiyin — ozgina shovqin (noise) bo'lsa, 7 ni 6 deb o'qib qo'yish mumkin. Ikkita holatni ("bor/yo'q") ajratish esa nihoyatda ishonchli. Mana shu ishonchlilik uchun kompyuterlar ikkilik sistemada ishlaydi.
Bitta 0 yoki 1 — bu bit (binary digit) deyiladi. Bu axborotning eng kichik bo'lagi.
2.3. Bit, bayt va o'lchov birliklari
Bitta bit juda kam ma'lumot beradi — atigi "ha yoki yo'q". Shuning uchun bitlar guruhlanadi. 8 ta bit birlashsa — bir bayt (byte) hosil bo'ladi.
Nega aynan 8? 8 bit bilan $2^8 = 256$ xil turli kombinatsiya yasash mumkin (00000000 dan 11111111 gacha). 256 ta belgi — lotin alifbosi, raqamlar, tinish belgilari uchun (dastlabki davrda) yetarli edi. Shuning uchun bayt — ma'lumotning amaliy asosiy birligi bo'lib qoldi.
1 bit = 0 yoki 1
1 bayt = 8 bit 256 xil qiymat (2^8)
2 bayt = 16 bit 65 536 xil qiymat (2^16)
4 bayt = 32 bit ~4.3 milliard qiymat (2^32)
8 bayt = 64 bit juda katta (2^64)Kattaroq birliklar (diqqat — bu yerda eng ko'p uchraydigan chalkashlik bor):
| Birlik | To'liq nomi | Necha bayt | Izoh |
|---|---|---|---|
| KB | kilobyte | 1000 bayt | marketingda (disk hajmi) |
| KiB | kibibyte | 1024 bayt | aniq texnik o'lchov ($2^{10}$) |
| MB | megabyte | 1000 KB | |
| MiB | mebibyte | 1024 KiB | |
| GB | gigabyte | 1000 MB | |
| GiB | gibibyte | 1024 MiB |
Sababi: kompyuter 2 ning darajalari bilan ishlaydi, ya'ni $2^{10} = 1024$ tabiiy "yumaloq son". Lekin disk ishlab chiqaruvchilar marketingda 1000 ni ishlatadi (shuning uchun "500 GB" disk operatsion tizimda "465 GiB" bo'lib ko'rinadi). Ikkalasi har xil — buni bilish kerak.
2.4. Sanoq sistemalari: decimal, binary, hexadecimal
Biz odamlar o'nlik (decimal) sistemada o'ylaymiz — 10 ta raqam: 0–9. Buning sababi oddiy: qo'limizda 10 ta barmoq bor. Lekin bu — tabiat qonuni emas, balki shartli kelishuv. Boshqa asosli (base) sistemalar ham xuddi shunday ishlaydi.
Asosiy g'oya: har bir raqamning "og'irligi" (razryadi) asos darajalariga teng.
O'nlik sistemada 347 soni aslida:
347 = 3×10² + 4×10¹ + 7×10⁰
= 3×100 + 4×10 + 7×1
= 300 + 40 + 7Ikkilik (binary, asos = 2) sistemada 1011 soni:
1011 = 1×2³ + 0×2² + 1×2¹ + 1×2⁰
= 1×8 + 0×4 + 1×2 + 1×1
= 8 + 0 + 2 + 1 = 11 (o'nlikda)O'n oltilik (hexadecimal, asos = 16) sistema dasturlashda juda ko'p uchraydi (ranglar #FF5733, xotira manzillari 0x7ffe, baytlar). Unda 16 ta "raqam" bor: 0–9 va keyin A=10, B=11, C=12, D=13, E=14, F=15.
Nega hex qulay? Chunki bitta hex raqami aynan 4 bitga teng ($16 = 2^4$). Demak 1 bayt (8 bit) = aniq 2 ta hex raqami. Bu uzun binary qatorlarni qisqa va o'qishga oson qiladi:
Binary: 1111 0101 (8 bit, o'qish qiyin)
Hex: F 5 0xF5
Decimal: 245O'xshatish: binary — bu "1 va 0 lardan iborat juda uzun lenta". Hex esa o'sha lentani 4 talab guruhga bo'lib, har guruhga qisqa nom berish — xuddi telefon raqamini
991234567deb bo'lib o'qiganingizdek, esda saqlash osonroq.
2.5. Ma'lumot qanday saqlanadi? (matn, son, rasm)
Kompyuter faqat 0 va 1 ni biladi. Unda matn, rasm, musiqa qayerdan keladi? Javob: hammasi shartli kelishuvlar (encoding — kodlash) orqali sonlarga aylantiriladi.
Matn (text): Har bir harfga bir son biriktiriladi. Eski standart — ASCII: masalan A = 65, B = 66, a = 97, 0 (raqam belgisi) = 48. Bu son esa baytda binary ko'rinishida saqlanadi:
'A' 65 01000001 (1 bayt)ASCII faqat 128 ta belgini qamragan — o'zbek oʻ, gʻ, emoji , xitoy ieroglifi unga sig'magan. Shuning uchun zamonaviy standart — Unicode, va uning eng mashhur kodlash usuli — UTF-8. UTF-8 da oddiy lotin harfi 1 bayt, oʻ/gʻ kabi belgilar 2 bayt, emoji esa 4 baytgacha joy egallaydi. (Buni 0.4-bob va keyinchalik Buffer mavzusida yana ko'ramiz.)
Sonlar: butun sonlar (integer) to'g'ridan-to'g'ri binary'da saqlanadi. Kasr sonlar (3.14) esa floating point (suzuvchi nuqta) standarti (IEEE 754) bo'yicha saqlanadi — bu juda muhim, chunki aynan shu narsa 0.1 + 0.2 !== 0.3 muammosini keltirib chiqaradi (6-bo'limda batafsil).
Rasm: rasm — bu mayda nuqtalar (piksel) to'plami. Har bir pikselning rangi 3 ta son bilan beriladi: qizil (R), yashil (G), ko'k (B), har biri 0–255 oralig'ida (ya'ni 1 bayt). Demak bitta piksel ≈ 3 bayt. 1920×1080 rasm ≈ $1920 \times 1080 \times 3 ≈ 6.2$ MB (siqilmagan holda). Mana shuning uchun rasmlar JPEG, PNG formatlarida siqiladi (compression).
Asosiy xulosa: kompyuterda hamma narsa — son. Son esa — binary. Farqi faqat shundaki, biz o'sha sonni qaysi "kelishuv" bilan o'qiymiz. Aynan bitta bayt 01000001 — agar uni ASCII deb o'qisangiz 'A', agar son deb o'qisangiz 65, agar rang deb o'qisangiz 65 darajadagi qizillik. Ma'no — kontekstdan (talqindan) kelib chiqadi.
2.6. CPU — kompyuterning miyasi
CPU (Central Processing Unit — markaziy protsessor) — bu hisob-kitoblarni va buyruqlarni bajaradigan qism. U juda sodda ishlarni, lekin dahshatli tez bajaradi.
CPU ichidagi asosiy qismlar:
- ALU (Arithmetic Logic Unit) — arifmetik (qo'shish, ayirish) va mantiqiy (AND, OR, taqqoslash) amallarni bajaradi.
- Control Unit (boshqaruv bloki) — qaysi buyruq keyin bajarilishini boshqaradi.
- Registrlar — CPU ichidagi nihoyatda kichik va nihoyatda tez xotira hujayralari. Hozir ishlatilayotgan sonlar shu yerda turadi.
- Clock (soat) — CPU ritmini belgilaydi. "3 GHz protsessor" degani — sekundiga 3 milliard marta "taq" etadi, va har "taq"da bir (yoki bir nechta) sodda amal bajarilishi mumkin.
CPU har doim bitta sodda tsiklni takrorlaydi — fetch–decode–execute (olib kel – tushun – bajar):
┌──────────────────────────────────┐
▼ │
1. FETCH RAM'dan keyingi buyruqni olib keladi
│
▼
2. DECODE bu qanday buyruq ekanini tushunadi
│ (qo'shishmi? xotiradan o'qishmi?)
▼
3. EXECUTE buyruqni bajaradi (masalan ALU qo'shadi)
│
└──────────────────────────────────┘
(va yana boshidan, milliard marta/sek)Core (yadro) — bu aslida bitta to'liq CPU. "4 yadroli protsessor" degani — 4 ta ish bir vaqtda, haqiqatan parallel bajarilishi mumkin. Thread (oqim) — bu bajarilayotgan ishlar ketma-ketligi; bitta yadro ko'plab thread'larni juda tez navbatma-navbat (almashtirib) bajarib, go'yo bir vaqtda bo'layotgandek ko'rsatishi mumkin.
DIQQAT: JavaScript/Node.js asosan bitta threadda ishlaydi. Mana shuning uchun "event loop", "asinxron kod", "non-blocking" tushunchalari shunchalik muhim — biz 2.11 va 5.1 boblarda bunga chuqur kiramiz. Hozir shuni eslab qoling: bitta oshpaz (thread) bir vaqtda ko'p taom tayyorlayotgandek ko'rinishi, lekin aslida ularni tez almashtirib turishi mumkin.
2.7. RAM — qisqa muddatli, tez xotira
RAM (Random Access Memory — tezkor xotira) — dastur ishlayotgan paytda ma'lumotlarini saqlaydigan joy. Uning ikki muhim xususiyati bor:
- Tez — CPU undan ma'lumotni juda tez oladi (diskdan ancha tez).
- Vaqtinchalik (volatile) — tok o'chsa, hamma narsa o'chib ketadi. Shuning uchun yozayotgan hujjatingizni saqlamasdan kompyuter o'chsa, yo'qoladi — chunki u faqat RAM'da turardi.
RAM'ni juda katta kataklar (hujayralar) qatori deb tasavvur qiling. Har bir katakning manzili (address) bor (0, 1, 2, 3, ...) va har biriga bitta bayt sig'adi:
manzil: 0 1 2 3 4 5 ...
┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐
RAM: │ 72 │ │ 65 │ │ 76 │ │ 76 │ │ 79 │ │ .. │
└────┘ └────┘ └────┘ └────┘ └────┘ └────┘
'H' 'A' 'L' 'L' 'O'"Random access" degani — CPU istalgan manzilga bevosita, bir xil tezlikda murojaat qila oladi (kitobning istalgan sahifasini darrov ochgandek). Bu — keyin ko'radigan "ketma-ket o'qish" (masalan eski magnit lenta) ning aksi.
Dastur ishga tushganda, uning kodi va ma'lumotlari diskdan RAM'ga yuklanadi, chunki CPU faqat RAM (va undan ham tezroq registr/cache) bilan to'g'ridan-to'g'ri ishlaydi. let user = {...} deb yozganingizda, o'sha obyekt — RAM'ning bir bo'lagida yashaydi.
2.8. Disk — uzoq muddatli, doimiy xotira
Disk (HDD yoki SSD) — ma'lumotni doimiy saqlaydi. Tok o'chsa ham yo'qolmaydi (non-volatile). Fayllaringiz, suratlaringiz, operatsion tizim — hammasi shu yerda.
- HDD (Hard Disk Drive) — aylanadigan magnit disk. Arzon, hajmi katta, lekin sekin (mexanik harakat bor).
- SSD (Solid State Drive) — mexanik qismsiz, flesh-xotira. Qimmatroq, lekin HDD'dan o'nlab-yuzlab marta tez.
Disk RAM'dan ancha sekin, lekin ancha arzon va doimiy. Mana shu "tez lekin vaqtinchalik" (RAM) va "sekin lekin doimiy" (disk) o'rtasidagi savdo (trade-off) — butun kompyuter dizaynining markazida turadi.
2.9. Xotira ierarxiyasi (memory hierarchy) — eng muhim tushuncha
Bu bo'limning eng qimmatli g'oyasi shu. Kompyuterda xotira bir nechta darajada joylashgan — yuqoriga chiqqan sari tezroq, kichikroq, qimmatroq:
TEZLIK ▲ HAJM
│ ┌───────────────┐
eng tez │ │ Registrlar │ ~1 KB eng kichik
│ ├───────────────┤
│ │ L1 / L2 / L3 │ bir necha MB
│ │ Cache │
│ ├───────────────┤
│ │ RAM │ 8–64 GB
│ ├───────────────┤
│ │ SSD / Disk │ 256 GB – bir necha TB
eng sekin │ ├───────────────┤
▼ │ Tarmoq/Cloud │ ~cheksiz eng katta
└───────────────┘Tezlik farqi shunchalik kattaki, uni "inson o'lchovida" tasvirlash kerak. Agar registrdan ma'lumot olishni 1 sekund deb olsak (taxminiy nisbatlar):
| Qayerdan | Inson o'lchovida (taxminan) |
|---|---|
| Registr / L1 cache | 1 sekund |
| RAM | bir necha daqiqa |
| SSD | bir necha kun |
| HDD | bir necha oy |
| Tarmoq (boshqa shahar serveri) | bir necha yil |
Mana shuning uchun caching (tez-tez kerak bo'ladigan ma'lumotni tezroq joyga ko'chirib qo'yish) — dasturlashda hamma joyda uchraydi: CPU cache, Redis (5.21-bob), brauzer cache, Next.js cache (13.7-bob). Hammasining sababi — bitta: pastdagi sekin qatlamga kamroq murojaat qilish.
Cache aynan nega ishlaydi? U ikkita kuzatishga — lokallik (locality) tamoyiliga — tayanadi:
- Vaqtinchalik lokallik (temporal locality): hozir ishlatilgan ma'lumot tez orada yana kerak bo'lish ehtimoli yuqori (masalan, tsikldagi hisoblagich yoki tez-tez chaqiriladigan funksiya).
- Fazoviy lokallik (spatial locality): bir manzildagi ma'lumot kerak bo'lsa, uning yonidagi manzillar ham tez orada kerak bo'ladi (masalan, massiv elementlari xotirada ketma-ket joylashadi).
Shuning uchun CPU RAM'dan bittagina bayt emas, balki butun cache line (odatda 64 bayt) ni birato'la o'qiydi. Massivni tartib bilan aylanib chiqish (arr[0], arr[1], arr[2]...) cache uchun ideal: birinchi elementni o'qiganda, qo'shnilari ham allaqachon cache'ga tushgan bo'ladi. Mana shuning uchun massiv (ketma-ket xotira) ko'pincha bog'langan ro'yxatdan (linked list — xotirada tarqoq joylashgan) tezroq ishlaydi — garchi ikkalasida ham "bitta elementga murojaat" nazariy jihatdan bir xil ko'rinsa-da (buni 3-QISMda Big-O bilan birga ko'ramiz). Aksincha, kerakli ma'lumot cache'da topilmasa — bu cache miss deyiladi va CPU sekin RAM'ga borishga majbur bo'ladi (o'nlab marta sekinroq).
Amaliy xulosa: ikki algoritmning Big-O murakkabligi bir xil bo'lsa ham, xotirani ketma-ket (cache-friendly) ishlatadigani amalda bir necha barobar tez bo'lishi mumkin. "Mechanical sympathy" — temir qanday ishlashini hisobga olib kod yozish — senior dasturchining kuchli quroli.
Hayotiy o'xshatish — oshpaz:
- Registr/cache = oshpazning qo'lidagi narsalar (darrov ishlatadi).
- RAM = ish stoli ustidagi masalliqlar (bir necha qadam narida).
- Disk = omborxona (borib kelish kerak, sekin).
- Tarmoq = bozorga borib kelish (juda uzoq).
Yaxshi oshpaz eng ko'p kerak bo'ladigan narsalarni qo'li ostiga qo'yadi. Yaxshi dasturchi ham xuddi shunday — ma'lumotni qancha tez-tez kerak bo'lsa, shuncha "yuqori"da saqlaydi.
2.10. Manfiy sonlar va bitli amallar (two's complement, bitwise)
Yuqorida faqat musbat sonlarni ko'rdik. Lekin -5 kabi manfiy son binary'da qanday saqlanadi? "Minus belgisi" uchun alohida joy yo'q — xotirada faqat 0 va 1 bor. Yechim — ikkilik to'ldiruvchi (two's complement) usuli; deyarli barcha zamonaviy protsessorlar aynan shuni ishlatadi.
G'oya: eng chapdagi (eng katta razryadli) bit ishora biti (sign bit) vazifasini bajaradi. Sonni manfiyga aylantirish uchun: barcha bitlarni teskari qiling (NOT), so'ng natijaga 1 qo'shing. 8-bitli misol:
+5 = 00000101
teskari (NOT) = 11111010
+1 = 11111011 bu -5
8-bitli son qamrovi:
ishorasiz (unsigned): 0 ... 255 (00000000 ... 11111111)
ishorali (signed): -128 ... +127 (eng chap bit = ishora)Bu usul nega chiroyli? Chunki qo'shish va ayirish bitta sxema bilan ishlaydi. 5 + (-5) ni hisoblang: 00000101 + 11111011 = 1 00000000. 8 bitdan oshib ketgan bit ("carry") tashlab yuboriladi va natija 00000000 = 0 bo'ladi — to'g'ri! CPU ayirishni alohida o'rganishi shart emas: manfiy sonni qo'shish kifoya.
Endi bitli amallar (bitwise) — "hamma narsa son" g'oyasining bevosita davomi. Sonni bitlar to'plami deb qarab, ular ustida bevosita amal bajariladi:
| Amal | Nomi | Ma'nosi |
|---|---|---|
& |
AND | ikkala bit ham 1 bo'lsa 1 |
| |
OR | bittasi 1 bo'lsa 1 |
^ |
XOR | bitlar farq qilsa 1 |
~ |
NOT | har bitni teskari qiladi |
<< |
chapga surish | x << 1 = x ni 2 ga ko'paytirish |
>> |
o'ngga surish | x >> 1 = x ni 2 ga bo'lish (butun qism) |
Bular nega kerak: ruxsat/bayroqlarni (flags) bitta songa joylash, rang kanallari (RGBA), nihoyatda tez ko'paytirish/bo'lish, xeshlash va past darajali optimizatsiya. Amalda buni 4-bo'lim, Misol 6 da ko'rasiz.
DIQQAT (endianness): ko'p baytli son xotirada qaysi tartibda saqlanadi? Little-endian (eng kichik bayt oldin — x86, ARM) yoki big-endian (eng katta bayt oldin — tarmoq protokollari, "network byte order"). Bu farq Buffer va binary fayl/protokol bilan ishlaganda muhim (5.4-bob): bir tartibda yozilgan baytni boshqa tartibda o'qisangiz, son buziladi. JavaScriptda esa bitli amallar sonni avtomatik 32-bitli ishorali butun songa keltirib bajaradi — buni quyidagi misolda ko'rasiz.
3. Amaliy belgilash va birliklar (sintaksis)
Bu mavzu "kod sintaksisi" emas, lekin dasturlashda har kuni uchraydigan yozuvlar bor. Ularni o'qiy olish kerak:
0b1011 binary (ikkilik) yozuvi. "0b" prefiksi. = 11
0o17 octal (sakkizlik) yozuvi. "0o" prefiksi. = 15
0xFF hex (o'n oltilik) yozuvi. "0x" prefiksi. = 255
255 decimal (o'nlik), oddiy sonRanglar (CSS va dizaynda doim hex):
#FF0000 R=FF(255) G=00 B=00 to'liq qizil
#00FF00 R=00 G=FF(255) B=00 to'liq yashil
#000000 qora #FFFFFF oqO'lchov birliklarini o'qish:
512 MB o'rtacha rasm/hujjatlar uchun ko'p
8 GB odatdagi noutbuk RAM
1 TB odatdagi SSD hajmi
3.2 GHz CPU chastotasi (sekundiga 3.2 mlrd takt)
100 Mbps internet tezligi (megabit/sek, bit — bayt emas!)Diqqat: internet tezligi bitda (
Mbps— megabit), fayl hajmi esa baytda (MB— megabayt) o'lchanadi. 8 bit = 1 bayt. Shuning uchun "100 Mbps" internetda fayl taxminan100 / 8 = 12.5 MB/sektezlikda yuklanadi. Bu — provayderlar yoqtiradigan "marketing" chalkashligi.
4. Batafsil kod namunalari
Endi nazariyani kodda ko'ramiz. Bu yerda JavaScript ishlatamiz — chunki u sizda bor va keyin shu tilga chuqur kiramiz. Har bir muhim qatorga izoh berilgan. Bu kodlarni Node.js'da (node fayl.js) yoki brauzer konsolida ishlatib ko'rishingiz mumkin.
Misol 1 — Sanoq sistemalari orasida o'tkazish
// Bitta son — turli sistemalarda ko'rsatamiz.
const son = 245;
// toString(asos) — sonni boshqa sanoq sistemasidagi MATN ko'rinishiga o'giradi.
console.log(son.toString(2)); // "11110101" binary (ikkilik)
console.log(son.toString(8)); // "365" octal (sakkizlik)
console.log(son.toString(16)); // "f5" hex (o'n oltilik)
console.log(son.toString(10)); // "245" decimal (odatdagi)
// parseInt(matn, asos) — teskari amal: matnni o'sha asosdagi son deb o'qiydi.
console.log(parseInt("11110101", 2)); // 245 binary matnni songa
console.log(parseInt("f5", 16)); // 245 hex matnni songa
// JS'da sonni to'g'ridan-to'g'ri boshqa sistemada yozish ham mumkin:
console.log(0b11110101); // 245 0b = binary literal
console.log(0o365); // 245 0o = octal literal
console.log(0xf5); // 245 0x = hex literal
// Yuqoridagi uchalasi — AYNAN bir xil son. Faqat YOZILISHI har xil.Misol 2 — Harf qanday songa aylanishi (encoding)
const harf = "A";
// charCodeAt(0) — birinchi belgining Unicode (kod) raqamini qaytaradi.
console.log(harf.charCodeAt(0)); // 65 'A' ning kodi
// String.fromCharCode(son) — teskarisi: koddan harf yasaydi.
console.log(String.fromCharCode(66)); // "B"
// "HALLO" so'zidagi har bir harfning kodini ko'ramiz:
for (const ch of "HALLO") {
// ch — har bir harf; ch.charCodeAt(0) — uning son kodi
console.log(ch, "->", ch.charCodeAt(0));
}
// H -> 72 A -> 65 L -> 76 L -> 76 O -> 79
// Aynan shu sonlar RAM'da binary holatda saqlanadi.Misol 3 — Matn necha baytga aylanishini ko'rish (UTF-8)
// TextEncoder — matnni UTF-8 baytlar massiviga aylantiradigan brauzer/Node API.
const encoder = new TextEncoder();
const a = encoder.encode("A"); // oddiy lotin harfi
const b = encoder.encode("oʻ"); // o'zbekcha "oʻ"
const c = encoder.encode(""); // emoji
console.log(a.length); // 1 'A' UTF-8'da 1 bayt
console.log(b.length); // 3 'oʻ' (o + maxsus belgi) ko'proq bayt
console.log(c.length); // 4 emoji 4 bayt!
// XULOSA: matnning "uzunligi" (belgilar soni) va uning DISK/RAM'da
// egallaydigan BAYT hajmi — bu IKKI XIL narsa. Til o'zbekcha yoki
// emoji bo'lsa, bayt hajmi belgilar sonidan katta bo'ladi.Misol 4 — Bir bayt = 8 bit ekanini ko'rsatish
// 1 baytga sig'adigan eng katta son: 11111111 (binary) = 255
const engKatta = 0b11111111;
console.log(engKatta); // 255
// padStart(8, "0") — chap tomonni 0 bilan to'ldirib, doim 8 xonali qiladi.
// Shunda binary ko'rinishi to'liq 1 bayt (8 bit) bo'lib chiroyli ko'rinadi.
for (let n = 0; n <= 5; n++) {
console.log(n, "->", n.toString(2).padStart(8, "0"));
}
// 0 -> 00000000
// 1 -> 00000001
// 2 -> 00000010
// 3 -> 00000011
// 4 -> 00000100
// 5 -> 00000101
// Har bir ustun — bitta bit. Eng o'ngdagisi "1 lik", keyingisi "2 lik"...Misol 5 — Floating point haqiqati (eng mashhur "g'alati" hodisa)
// Kasr sonlar binary'da ANIQ saqlanmaydi (xuddi 1/3 ni o'nlikda
// 0.3333... deb cheksiz yozganimizdek, ba'zi kasrlar 2 lik sistemada cheksiz).
console.log(0.1 + 0.2); // 0.30000000000000004 (!!!)
console.log(0.1 + 0.2 === 0.3); // false shuning uchun === ishlamaydi
// To'g'ri taqqoslash: ikki son orasidagi farq juda kichik (epsilon) bo'lsa,
// ularni "teng" deb hisoblaymiz.
const teng = Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON;
console.log(teng); // true
// Pul bilan ishlaganda eng xavfsiz yo'l — eng kichik birlikni (tiyin/sent)
// BUTUN son sifatida saqlash. Masalan 19.99 so'mni 1999 tiyin deb saqlash.
const narx = 1999; // tiyinlarda — kasr yo'q, xato yo'q
console.log(narx / 100); // 19.99 faqat ko'rsatishda bo'lamizMisol 6 — Bitli amallar (bitwise) amalda
// 1) Asosiy bitli amallar (JS ularni 32-bitli butun son sifatida bajaradi).
console.log(5 & 3); // 1 0101 & 0011 = 0001
console.log(5 | 3); // 7 0101 | 0011 = 0111
console.log(5 ^ 3); // 6 0101 ^ 0011 = 0110 (farq qilgan bitlar)
console.log(~5); // -6 bitlarni teskari (two's complement natijasi!)
console.log(5 << 1); // 10 chapga surish = ×2
console.log(5 >> 1); // 2 o'ngga surish = ÷2 (butun qism)
// 2) AMALIY: bir nechta ruxsatni bitta songa joylash (flags / bitmask).
// Unix fayl ruxsatlari (chmod 755) aynan shu g'oyaga asoslanadi.
const OQISH = 1; // 001
const YOZISH = 2; // 010
const BAJARISH = 4; // 100
// Foydalanuvchiga o'qish + yozish beramiz (kerakli bitlarni yoqamiz):
let ruxsat = OQISH | YOZISH; // 011 = 3
console.log(ruxsat); // 3
// "Yozish ruxsati bormi?" — AND bilan bitni tekshiramiz:
console.log((ruxsat & YOZISH) !== 0); // true
console.log((ruxsat & BAJARISH) !== 0); // false
// Bitta ruxsatni o'chirish (yozishni olib tashlash): & ~FLAG
ruxsat = ruxsat & ~YOZISH; // 001 = 1
console.log(ruxsat); // 1 — faqat o'qish qoldi
// XULOSA: bitta butun son ichida 32 tagacha "ha/yo'q" bayroqni saqlash mumkin —
// bu xotira tejaydi va tekshirish nihoyatda tez (bitta CPU amali).5. To'g'ri va noto'g'ri holatlar
1) Kasr sonlarni === bilan taqqoslash
// NOTO'G'RI — floating point xatosi tufayli kutilmagan natija
if (0.1 + 0.2 === 0.3) { /* bu blok HECH QACHON ishlamaydi */ }
// TO'G'RI — epsilon (juda kichik farq) bilan taqqoslash
if (Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON) { /* ishlaydi */ }Nega: kasr sonlar binary'da yaxlitlanadi; aniq tenglik ishonchsiz.
2) Pulni kasr son sifatida saqlash
// NOTO'G'RI — moliyaviy hisoblarda yaxlitlash xatolari yig'iladi
let balans = 0.0;
for (let i = 0; i < 10; i++) balans += 0.1;
console.log(balans); // 0.9999999999999999 — 1 emas!
// TO'G'RI — eng kichik birlikni butun songa aylantirib saqlash
let balansTiyin = 0;
for (let i = 0; i < 10; i++) balansTiyin += 10; // 0.1 so'm = 10 tiyin
console.log(balansTiyin / 100); // 1 aniq3) Birliklarni chalkashtirish (bit vs bayt, KB vs KiB)
// NOTO'G'RI — "100 Mbps internetda 100 MB fayl 1 sekundda yuklanadi"
// deb o'ylash. Mbps — megaBIT, MB — megaBAYT. 8 barobar farq!
// TO'G'RI — bitni baytga o'tkazib hisoblash
const tezlikMbps = 100;
const tezlikMBps = tezlikMbps / 8; // 12.5 MB/sek
const faylMB = 100;
console.log(faylMB / tezlikMBps, "sekund"); // 8 sekund (taxminan)4) Katta fayllarni butunlay RAM'ga yuklash
// NOTO'G'RI — 5 GB faylni bir varakayiga RAM'ga o'qish
// const data = fs.readFileSync("katta-video.mp4"); // RAM portlaydi!
// TO'G'RI — stream (oqim) orqali bo'lak-bo'lak o'qish (5.4-bobda chuqur)
// fs.createReadStream("katta-video.mp4").pipe(...);Nega: RAM cheklangan (masalan 8 GB). 5 GB faylni butunlay yuklash xotirani to'ldiradi va dastur qulaydi. Disk katta, RAM kichik — buni esda tuting.
6. Keng tarqalgan xatolar va yechimlari
Xato 1 — RangeError: Maximum call stack size exceeded
function cheksiz() {
return cheksiz(); // o'zini to'xtovsiz chaqiradi
}
cheksiz();
// RangeError: Maximum call stack size exceededSababi: har bir funksiya chaqiruvi RAM'dagi maxsus joyni — call stackni — egallaydi. Cheksiz rekursiya stack'ni to'ldiradi va u "toshib ketadi". Yechimi: rekursiyaga to'xtash sharti (base case) qo'yish, yoki tsikl (loop) bilan yozish. (Rekursiyani 3.11-bobda chuqur ko'ramiz.)
Xato 2 — JavaScript heap out of memory
FATAL ERROR: Reached heap limit Allocation failed -
JavaScript heap out of memorySababi: dastur RAM'da haddan tashqari ko'p ma'lumot yig'di (masalan cheksiz o'sib boruvchi massiv, yoki memory leak). Yechimi: ma'lumotni stream bilan qismlarga bo'lib ishlash; keraksiz havolalarni (reference) tozalash; kerak bo'lsa Node'ga ko'proq xotira berish (node --max-old-space-size=4096).
Xato 3 — butun son chegarasidan oshib ketish (integer overflow / precision)
console.log(9007199254740991 + 1); // 9007199254740992 (to'g'ri, oxirgi aniq son)
console.log(9007199254740991 + 2); // 9007199254740992 (XATO! 2 qo'shilmadi)Sababi: JS oddiy number 64-bitli floating point bo'lib, faqat Number.MAX_SAFE_INTEGER (≈ 9 kvadrilion) gacha butun sonlarni aniq saqlaydi. Yechimi: undan katta butun sonlar uchun BigInt ishlatish:
console.log(9007199254740991n + 2n); // 9007199254740993n aniq (n — BigInt)Xato 4 — NaN (Not a Number) paydo bo'lishi
console.log("salom" * 2); // NaN
console.log(0 / 0); // NaN
console.log(parseInt("xyz")); // NaNSababi: son bo'lmagan narsa ustida arifmetik amal bajarildi. Yechimi: kirish ma'lumotini ishlatishdan oldin Number.isNaN(x) bilan tekshirish. (Bu — 0.6-bobdagi "kirishni tekshirish" tamoyiliga bog'lanadi.)
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
Bu fundamental bilim butun kitob davomida qayta-qayta chiqadi. Mana xaritasi:
- Event loop & async (2.11, 5.1): Node bitta thread'da ishlaydi 2.6-bob — shuning uchun asinxronlik kerak.
- Buffer & Streams 5.4-bob: baytlar bilan to'g'ridan-to'g'ri ishlash; katta fayllarni RAM'ni to'ldirmasdan o'qish (5-bo'limga qara).
- Big-O murakkabligi 3.1-bob: algoritm tezligi — aslinda "CPU necha amal bajaradi" va "necha RAM kerak" degani.
- Ma'lumotlar bazasi indekslari (6.3, 6.9): indeks — bu disk (sekin) o'rniga RAM'da tez qidirish uchun tuzilma. Xotira ierarxiyasining 2.9-bob amaliy ko'rinishi.
- Caching: Redis 5.21-bob, Next.js cache 13.7-bob: "sekin qatlamga kam murojaat" tamoyili 2.9-bob.
- Xavfsizlik — parol xeshlash (5.15, 14.3): xesh — baytlar ustidagi matematik amal; binary tushunchasiga tayanadi.
- Performance 11.11-bob: re-render'larni kamaytirish — aslida CPU ishini kamaytirish.
Boshqacha aytganda: bu bobni yaxshi tushunsangiz, keyingi 150 bob osonroq bo'ladi.
8. Eng yaxshi amaliyotlar (best practices)
- Hamma narsa — son, son esa kontekstga bog'liq. "Bu bayt nimani anglatadi?" deb so'rashga odatlaning — matnmi, sonmi, ranglarmi?
- Pul va aniq hisoblarda hech qachon floating point ishlatmang. Eng kichik birlikni butun son (yoki maxsus
decimalkutubxona) sifatida saqlang. - Xotira cheklangan resurs — uni hurmat qiling. Katta ma'lumotni stream bilan ishlang, keraksiz havolalarni ushlab turmang.
- "Tez = yuqori qatlam" tamoyilini eslab turing. Tez-tez kerak bo'ladigan ma'lumotni cache'lang; sekin qatlamga (disk, tarmoq) kamroq boring.
- Birliklarni doim aniqlashtiring.
MBmiMiBmi?bitmibaytmi? Bu — real bug'larning manbai. BigIntni katta butun sonlar uchun biling. ID, vaqt belgisi (timestamp), moliyaviy summalar katta bo'lsa kerak bo'ladi.- O'lchamlar haqida "taxminiy his" rivojlantiring. "Bu massivda 1 million obyekt bo'lsa, taxminan necha MB RAM yeydi?" deb chama qila olish — senior dasturchining belgisidir.
9. Amaliy loyiha: "Sanoq Sistemalari va Bayt Kalkulyatori"
Bu mavzuni mustahkamlash uchun kichik, lekin chuqur loyiha. Hech qanday kutubxonasiz, faqat sof JavaScript va Node.js bilan (terminal dasturi) yoki oddiy HTML sahifa sifatida.
Maqsad
Foydalanuvchi son yoki matn kiritganda, uni turli sanoq sistemalarida va bayt ko'rinishida ko'rsatadigan kalkulyator yozish. Maqsad — sonlar va kodlash "ko'rinmas" emas, balki ko'z bilan ko'riladigan bo'lishi.
Talablar (requirements)
- Son rejimi: foydalanuvchi o'nlik son kiritsa (masalan
245), dastur uni:- binary (
11110101), - octal (
365), - hex (
f5) ko'rinishida chiqarsin. Binary doim to'liq baytlarga (8, 16, 24 bit...)0bilan to'ldirib ko'rsatilsin.
- binary (
- Teskari rejim: foydalanuvchi binary yoki hex kiritsa (masalan
0xFFyoki0b1011), dastur uni o'nlikka aylantirsin. - Matn rejimi: foydalanuvchi so'z kiritsa (masalan
Salom), dastur:- har bir harfning Unicode kodini,
- har bir harfning binary (8-bit) ko'rinishini,
- butun so'z UTF-8'da necha bayt ekanini chiqarsin.
- Bayt hisoblagich: foydalanuvchi
1.5 GByoki500 MiBkabi hajm kiritsa, uni baytlarga aylantirsin (KB/KiB farqini to'g'ri hisobga olsin).
Maslahatlar (hint)
Number.prototype.toString(asos)vaparseInt(matn, asos)— asosiy qurolingiz.padStart(8, "0")bilan binary'ni chiroyli, to'liq baytga to'ldiring.- Matn baytlari uchun
new TextEncoder().encode(str).lengthdan foydalaning. - Kiritilgan qiymat son ekanini
Number.isNaN()bilan tekshiring (6-bo'limni eslang). - Terminal versiyasi uchun
process.argv(buyruq qatori argumentlari) yokireadlinemodulidan foydalanishingiz mumkin (buni 0.3 va 5.3-boblarda ko'ramiz — hozir oddiyprompt/o'zgaruvchi ham bo'ladi). - KB/KiB:
1 KB = 1000,1 KiB = 1024. Lug'at (object) tuzib, har birlikka ko'paytuvchini bog'lang.
"Tayyor" mezonlari (acceptance criteria)
-
245kiritilganda11110101,365,f5to'g'ri chiqadi. -
0xFFkiritilganda255chiqadi. -
Salomkiritilganda har bir harf kodi vaqo'shilsa bayt soni to'g'ri o'zgaradi. -
1 KiB1024,1 KB1000to'g'ri farqlanadi. - Noto'g'ri kirish (
"abc"ni son rejimida) berilganda dastur qulamaydi, balki tushunarli xabar beradi. - (Bonus) Natijalar jadval ko'rinishida chiroyli chiqadi.
Yechim kodini bu yerda bermaymiz — buni o'zingiz yozishingiz kerak, chunki haqiqiy o'rganish aynan yozish jarayonida bo'ladi.
10. Xulosa va keyingi bobga ko'prik
Bu bobda kompyuterning eng tubidagi haqiqatlarni o'rgandik:
- Kompyuter input process output mashinasi; ichida hammasi 0 va 1 (binary) bilan ifodalanadi, chunki tranzistorlar ikki holatli.
- Bit — eng kichik birlik; 8 bit = 1 bayt. Hex (
0x) — baytlarni qisqa yozish usuli. - Hamma narsa — son, faqat talqini (encoding) farq qiladi: matn (ASCII/UTF-8), rasm (RGB), kasr son (floating point).
- Manfiy sonlar ikkilik to'ldiruvchi (two's complement) bilan saqlanadi; bitli amallar (
& | ^ ~ << >>) bayroq, ruxsat va past darajali optimizatsiyada ishlatiladi. - Cache va lokallik: xotirani ketma-ket (cache-friendly) ishlatish bir xil Big-O da ham kodni amalda tezlashtiradi — massiv
vslinked list. - CPU — fetch–decode–execute tsiklini milliard marta/sek takrorlaydi; yadro parallel ish, JS esa asosan bitta thread.
- Xotira ierarxiyasi: registr cache RAM disk tarmoq. Yuqoriga chiqqan sari tez, kichik, qimmat. RAM — tez lekin vaqtinchalik; disk — sekin lekin doimiy.
- Bu bilimlar floating point xatolari, memory leak, Big-O, indeks, cache kabi keyingi mavzularning poydevori.
Keyingi bob — 0.2-bob: Operatsion tizimlar va fayl tizimi. Endi temirni (hardware) tushundik; navbat — o'sha temirni boshqaradigan va biz har kuni ishlaydigan operatsion tizim (Windows, Linux, macOS) hamda fayllar qanday tashkil etilishiga. Bu — terminal 0.3-bob va Node.js 0.7-bob oldidan zarur ko'prik.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!