~/writing/from-keypress-to-screen $
    08/08
    intro ⏻
    LEVEL 3 — THE BRIDGESপর্ব ০৮/০৮~১৫ মিনিট

    Keyboard-এর 'A' থেকে Screen-এর 'A'

    এক keystroke-এর ভেতরে যা কিছু ঘটে — সিরিজের সব layer একসাথে

    Keyboard-এ 'A' চাপলেন। এক মুহূর্ত পর screen-এ 'A' ফুটে উঠল।

    আপনার কাছে মনে হলো instant। কোনো delay টের পাননি, কোনো অপেক্ষাও করতে হয়নি। আঙুল নামল আর অক্ষরটা চলে এল।

    কিন্তু "instant" মানে literally zero time নয়। আপনার আঙুলের চাপ থেকে screen-এ আলো জ্বলা পর্যন্ত বেশ কয়েকটি আলাদা hardware এবং software layer কাজ করে।

    এই সিরিজে এতদিন আমরা এই system-গুলোকে আলাদা আলাদা করে দেখেছি। আজ দেখব সবাই একসাথে কীভাবে কাজ করে। একটা মাত্র keystroke-কে follow করে পুরো পথটা হেঁটে যাব — আঙুলের চাপ থেকে শুরু করে চোখে আলো পড়া পর্যন্ত।

    01

    প্রথম চমক: keyboard-এর ভেতরেও একটা ছোট computer আছে

    'A' চাপলে সরাসরি laptop-এর main CPU-তে কিছু যায় না। তার আগে সেই signal-কে থামতে হয় keyboard-এর নিজের ভেতরে বসে থাকা একটা ছোট্ট computer-এ।

    শুনতে অদ্ভুত লাগতে পারে। Keyboard তো একটা input device মাত্র, তার আবার নিজের computer কেন থাকবে? কিন্তু keyboard-এর ভেতরে সাধারণত একটা ছোট controller chip থাকে। এতে processor logic, কিছু memory আর keyboard-এর firmware থাকে। তার কাজ হলো key press detect করা আর সেটাকে computer-এর জন্য meaningful input data-তে পরিণত করা।

    অনেক keyboard-এ key-গুলো একটা matrix আকারে সাজানো — সারি আর কলামের intersection-এ key বসে। Controller বারবার সেই matrix scan করে দেখে কোন key-এর electrical state বদলেছে। প্রতিটা key-এর জন্য আলাদা তার টানার দরকার হয় না; সারি আর কলামের সংযোগই বলে দেয় কোন key চাপা হয়েছে।

    যতক্ষণ কোনো key চাপা না হচ্ছে, কোনো কলামেই কিছু ধরা পড়ে না। কিন্তু যেই কোনো key চাপা হয়, সেই key-এর নিচের switch-এর দুইটা metal contact একসাথে লেগে যায়, সেই সারি আর সেই কলামের মাঝে circuit complete হয়ে যায়, আর chip ঐ কলামে voltage দেখতে পায়।

    scan cycle
    Keyboard matrix
          ↓
    controller scans
          ↓
    which key changed?
          ↓
    input report / usage code

    ধরুন 'A' key press detect হলো। USB keyboard হলে controller সাধারণত USB HID (Human Interface Device) protocol ব্যবহার করে host-এর কাছে একটা input report পাঠায়। সেই report-এ 'A' key-এর জন্য একটা নির্দিষ্ট usage code থাকতে পারে — USB HID Usage Tables-এ 0x04 হলো "Keyboard a and A"।

    খেয়াল করুন — এই 0x04 character 'A'-এর ASCII code নয়। এটা keyboard-এর কোন key-এর কথা বলা হচ্ছে, সেটার একটা code। অক্ষরে রূপান্তরটা হবে পরে, OS-এর স্তরে — layout বদলালে একই key অন্য অক্ষরও হতে পারে।

    মানে laptop-এর main CPU কিছু জানার আগেই keyboard-এর নিজের controller একটা পুরো কাজ সেরে ফেলেছে। Electrical change পড়া হয়েছে, সিদ্ধান্ত নেওয়া হয়েছে, digital input information তৈরি হয়েছে।

    আর সেই controller-এর processor-ও কিন্তু আমাদের দেখা সেই একই নিয়মে চলে — fetch করে, decode করে, execute করে। শুধু scale-টা অনেক ছোট। নিচের যন্ত্রে একটা key চেপে scan cycle-টা দেখুন:

    যন্ত্র ০১ — THE SCAN
    সারি ১/৪
    KEY MATRIX · সারি × কলাম
    R1
    R2
    R3
    R4
    C1
    C2
    C3
    C4
    ৪×৪ = ১৬টা key, মাত্র ৮টা pin-এ
    CHIP
    কিছু নেই…
    LOOKUP
    —
    USB OUT
    —
    chip সারি ১/৪-এ current দিচ্ছে, সব কলাম একসাথে পড়ছে… সারি ৩-এ পৌঁছালে ধরা পড়বে।
    প্রতিটা key-এর আলাদা তার নেই। Chip একটা করে সারিতে current পাঠায় আর সব কলাম একসাথে পড়ে — চাপা key যেই সারিতে, সেই সারির পালা এলেই তার কলামে voltage ধরা পড়ে। সারি আর কলামের সংযোগ থেকেই বোঝা যায় কোন key — আর সেই key-এর জন্য HID usage code পাঠানো হয় (এগুলো ASCII নয়)।
    02

    Interrupt: CPU-কে জানানো

    USB-এর মাধ্যমে keyboard-এর input information laptop-এ পৌঁছাল। Motherboard-এ বসে থাকা USB controller সেটা receive করল — এই controller একটা আলাদা chip, CPU-র বাইরে, যার কাজ USB device-এর সঙ্গে কথা বলা।

    এখন data এসেছে, কিন্তু CPU এই মুহূর্তে অন্য কাজ করতে পারে — হয়তো Chrome-এর কোনো JavaScript চালাচ্ছে, বা video decode করছে। তাকে জানাতে হবে যে একটা hardware event ঘটেছে।

    এই জানানোর একটা mechanism হলো interrupt। USB subsystem host CPU-কে জানায় যে নতুন data এসেছে, আর CPU তার বর্তমান execution-এর উপযুক্ত point থেকে interrupt handling-এর দিকে যায়।

    তার আগে CPU-কে এতটুকু state সংরক্ষণ করতে হয়, যাতে পরে আগের execution-এ ফিরে আসা যায়। তারপর privileged OS code interrupt-এর কাজটা সামলায়।

    এখানে একটা গুরুত্বপূর্ণ distinction: interrupt আসা মানেই context switch নয়। Interrupt handle করার পর CPU আগের কাজেই ফিরে যেতে পারে। আবার interrupt handling-এর ফলে কোনো task runnable হলে scheduler পরে অন্য task-কে CPU-তে চালাতেও পারে।

    interrupt handling
    current execution
           ↓
       interrupt
           ↓
    OS interrupt handling
           ↓
    resume previous work
            or
    scheduler runs another task

    অর্থাৎ interrupt মূলত একটা বার্তা — "CPU, hardware-এ একটা event ঘটেছে, এটা handle করো।"

    03

    OS-এর ভেতরে: এই event কার জন্য?

    Interrupt handler চলতে শুরু করে। এই handler আসলে কী জিনিস? এটা Linux বা Windows kernel-এর একটা অংশ, যেটা বছর কয়েক আগে কোনো developer লিখেছিলেন। তারপর সেটা compile হয়ে machine code হয়েছে, আর আপনার laptop boot হওয়ার সময় সেই machine code memory-তে load হয়েছে। এই মুহূর্তে সেই বহু পুরনো compiled code-ই চলছে।

    তারপর OS-এর keyboard driver সেই input data পড়ে বোঝে — কোন key চাপা হয়েছে। সেখান থেকে OS একটা keyboard event তৈরি করে নিজের উপরের স্তরে পাঠিয়ে দেয়।

    এখন প্রশ্ন — এই event কোন application-এর জন্য? আপনার laptop-এ তো এই মুহূর্তে অনেকগুলো program চলছে। Key press সাধারণত সবাইকে পাঠানো হয় না।

    Desktop-এর input/window system জানে কোন window এই মুহূর্তে focused। ধরা যাক সেটা VS Code। তাহলে event সেই application-এর জন্য deliver করা হবে।

    এরপর application যদি এই মুহূর্তে CPU-তে না চলে, তাকে runnable করা হতে পারে। Scheduler তার policy অনুযায়ী পরে তাকে CPU-তে চালানোর সুযোগ দেয়।

    event delivery
    keyboard event
          ↓
    OS input handling
          ↓
    application becomes runnable
          ↓
    scheduler
          ↓
    application runs

    এখানেও আগের distinction-টা মনে রাখুন — event আসা আর context switch একই ঘটনা নয়। Application তখন CPU-তেই থাকতে পারে; তখন আলাদা করে context switch-এর দরকার নাও হতে পারে।

    আর যদি সত্যিই অন্য process-এর thread থেকে VS Code-এর thread-এ execution যায়, তখন প্রয়োজন অনুযায়ী তাদের execution state আর virtual memory context বদলায় — Article 6-এ যেভাবে দেখেছিলাম।

    04

    App জেগে উঠল

    ধরুন আপনি একটা text editor-এ টাইপ করছেন — এই মুহূর্তে সেটাই focused application। Event তার কাছে পৌঁছায়, আর application-এর ভেতরের একটা event handler বুঝতে পারে: user একটা key চেপেছে।

    তবে event সাধারণত app-কে মাঝপথে ধাক্কা দিয়ে থামায় না। App-এর নিজের একটা loop আছে, যেটা একটার পর একটা event নিয়ে কাজ করে। আমাদের keypress সেই সারিতেই গিয়ে বসেছিল, আর app CPU-তে সুযোগ পেয়ে সেটা তুলে নিয়েছে।

    app-এর loop
    event waiting in the queue
              ↓
    app takes the next event
              ↓
        update state
              ↓
    mark the UI as needing a redraw
              ↓
      wait for the next event

    "State update" বলতে এখানে কী বোঝায়? Editor-এর কাছে আপনার file-টা memory-তে একটা data structure হিসেবে আছে — মোটামুটি character-এর একটা তালিকা। Article 2-তে দেখেছি, প্রতিটা character memory-তে সংখ্যা হিসেবেই থাকে। তাই কাজটা আসলে এই — cursor যেখানে আছে সেখানে সেই সংখ্যাটা ঢোকানো, আর cursor এক ধাপ এগিয়ে দেওয়া।

    আর একটা keypress-এ প্রায়ই এর চেয়ে বেশি কিছু ঘটে। Undo history-তে একটা entry যোগ হয়, যাতে Ctrl+Z কাজ করে। Syntax highlighting আবার হিসাব হয়। Autocomplete হয়তো নতুন suggestion খুঁজতে শুরু করে। এক অক্ষর টাইপ করলেও editor-এর ভেতরে কয়েকটা ছোট কাজ একসঙ্গে জেগে ওঠে।

    কিন্তু খেয়াল করুন — app নিজে screen-এ কিছু আঁকেনি। সে শুধু নিজের state বদলেছে, আর ঠিক করেছে UI-র কোন অংশটা আবার আঁকা দরকার। আঁকার কাজটা এর পরের ধাপ।

    আর "আঁকা" মানে screen-এ pixel বসানো। কোন pixel-এ কী রং হবে, সেটা কে ঠিক করবে?

    05

    অক্ষর থেকে pixel

    এখানে font system কাজে নামে। আপনার editor-এ যে font ব্যবহার করছেন — Consolas, Fira Code, যাই হোক — তার font data system বা application-এর memory/cache-এ আগে থেকেই থাকতে পারে। না থাকলে প্রয়োজন অনুযায়ী load করা হয়।

    Font file-এ প্রতিটা character-এর জন্য একটা করে shape-এর বর্ণনা থাকে। বেশিরভাগ modern font-এ সেই বর্ণনা vector আকারে — মানে গাণিতিক curve দিয়ে বলা থাকে অক্ষরটার আকৃতি কেমন হবে। এর সুবিধা হলো, যেকোনো size-এ scale করলেও অক্ষরটা ঝাপসা হয় না।

    কিন্তু display-এ শেষ পর্যন্ত pixel দরকার। তাই সেই shape-কে আপনার current font size অনুযায়ী pixel grid-এর ওপর বসাতে হয়। এই প্রক্রিয়ার নাম rasterization।

    rasterization
    'A' character
          ↓
      font shape
          ↓
     rasterization
          ↓
    pixel information

    এখন 'A' আর শুধু একটা character হিসেবে নেই। তার shape screen-এর ছোট একটা অঞ্চলের pixel information-এ পরিণত হয়েছে, যার প্রতিটা pixel-এর জন্য brightness বা color information দরকার। Article 2-তে দেখেছিলাম কীভাবে ছবির pixel value শেষ পর্যন্ত bit-এ represent হয় — এখানেও সেই একই idea ফিরে এল। একটা abstract অক্ষর ধীরে ধীরে screen-এর physical image-এর দিকে এগোচ্ছে। নিচের যন্ত্রে vector থেকে pixel-এ যাওয়াটা দেখুন:

    যন্ত্র ০২ — RASTERIZE
    VECTOR (font)
    →
    PIXEL (screen)
    ৩৫ pixel grid
    বাঁয়ে মসৃণ vector A। "rasterize" চাপুন — screen-এর জন্য pixel-এ ভাঙবে।
    Font-এ অক্ষর থাকে মসৃণ vector curve হিসেবে, কিন্তু screen বোঝে শুধু pixel। Rasterization সেই curve-কে current size-এর pixel grid-এ ভাঙে — size যত বড়, pixel তত বেশি, অক্ষর তত পরিষ্কার।
    06

    Frame থেকে আলো

    এখন application-এর updated UI-কে screen-এর জন্য একটা final image-এ পরিণত করতে হবে। Window compositor বিভিন্ন visible window-এর content একত্র করে screen-এর final frame তৈরি করতে পারে — সে জানে কোন window কোথায় বসানো।

    তারপর graphics/display pipeline সেই frame-কে একটা display buffer-এ প্রস্তুত করে, যেখান থেকে display hardware সেটা monitor-এর দিকে পাঠাতে পারে।

    display path
    Application UI
          ↓
      rendering
          ↓
      compositor
          ↓
      final frame
          ↓
     display buffer
          ↓
       monitor

    60 Hz display হলে screen প্রতি second-এ ৬০টা refresh cycle চালায় — প্রতিটা cycle মোটামুটি ১৬.৬৭ millisecond। তবে এর মানে এই নয় যে GPU ঠিক প্রতি ১৬.৬৭ ms অন্তর পুরো ছবিটা একসাথে cable-এ ছুঁড়ে দেয়; display system frame-এর data ধারাবাহিকভাবে scan out করে।

    HDMI বা DisplayPort cable-এর মধ্য দিয়ে সেই digital information electrical signal হিসেবে যায়, আর তার মাধ্যমে pixel data ও display control information monitor-এ পৌঁছায়।

    এই সিরিজের একদম প্রথম আর্টিকেলে আমরা যেখান থেকে শুরু করেছিলাম, ঘুরে ফিরে সেই electrical signal-এই ফিরে এলাম।

    Monitor-এর ভেতরের display electronics সেই data অনুযায়ী panel drive করে। LCD-তে liquid crystal দিয়ে ঠিক করা হয় backlight-এর কতটা আলো প্রতিটা pixel দিয়ে যাবে; OLED-এ প্রতিটা pixel নিজেই আলো তৈরি করে।

    'A'-এর shape অনুযায়ী নির্দিষ্ট pixel-গুলোতে উপযুক্ত আলো তৈরি হলো। Photon বেরিয়ে এসে আপনার চোখে পড়ল।

    আপনি screen-এ 'A' দেখলেন।

    07

    একটামাত্র keypress-এ কতগুলো layer

    আপনার কাছে পুরোটা instant মনে হয়েছে। এক আঙুলের চাপ, সাথে সাথে অক্ষর। নিচের যন্ত্রে পুরো relay-টা এক ধাপ এক ধাপ করে চালিয়ে দেখুন — keypress থেকে চোখে আলো পর্যন্ত:

    যন্ত্র ০৩ — THE RELAY ('A' → screen)
    ধাপ ১/১৩
    HW'A' চাপলেন — switch-এর contact লাগল
    HWkeyboard controller matrix scan করে, HID input report পাঠায়
    HWUSB subsystem সেটা পায়, CPU-কে interrupt দিয়ে জানায়
    KCPU ফেরার মতো state রেখে privileged code-এ যায়
    KOS-এর interrupt handling input data process করে
    Kdriver + input subsystem একটা keyboard event বানায়
    Kwindow system event-টা focused application-এর জন্য পাঠায়
    Kapplication runnable; scheduler তাকে CPU-তে চালায়
    Uapp-এর event handler state বদলায় — cursor-এ 'A'
    Ufont system 'A'-এর shape rasterize করে pixel information বানায়
    Kcompositor final frame বানায়, display buffer-এ প্রস্তুত হয়
    HWdisplay pipeline cable দিয়ে monitor-এ frame পাঠায়
    HWpixel আলো ছাড়ল — photon চোখে পড়ল, 'A' দেখলেন
    HWKERNELUSER
    privilege transition: ০
    HW hardware · K kernel · U user। ধাপ ১/১৩
    এক keypress-এর পুরো chain: keyboard controller, HID, interrupt, OS-এর input handling, scheduler, application event, rasterization, compositor, display — প্রতিটা layer নিজের কাজ করে পরেরজনের হাতে তুলে দেয়। এটা একটা conceptual path; আসল ধাপ আর timing system ভেদে আলাদা।

    কিন্তু এই ছোট্ট ঘটনার ভেতরে আমরা অনেকগুলো layer দেখতে পেলাম:

    the whole chain
    Finger
      ↓
    Keyboard switch
      ↓
    Keyboard controller
      ↓
    USB / HID
      ↓
    Interrupt + OS input handling
      ↓
    Application event
      ↓
    Editor state
      ↓
    Font + rasterization
      ↓
    Compositor / graphics pipeline
      ↓
    Display hardware
      ↓
    Light
      ↓
    Your eye

    প্রতিটা layer-এর কাজ আলাদা। Keyboard জানে না VS Code কীভাবে text edit করে। OS জানে না 'A'-এর glyph দেখতে কেমন। Font system জানে না keyboard থেকে event কীভাবে এসেছে। Display hardware জানে না আপনি কোন editor ব্যবহার করছেন।

    তবু তারা একে অন্যের সঙ্গে কাজ করতে পারে। কেন?

    কারণ প্রতিটা layer-এর মধ্যে একটা defined interface আছে — এক layer কী ধরনের information দেবে, পরের layer সেটাকে কীভাবে interpret করবে, আর তার output কী হবে।

    এই ধারণাটাই abstraction। একটা layer-এর ভেতরটা না জেনেও তার interface ব্যবহার করা যায়।

    এই কারণেই keyboard-এর firmware লেখা engineer-কে VS Code-এর code বুঝতে হয় না। আর VS Code-এর developer-কে LCD panel-এর liquid crystal physics বুঝে keypress handler লিখতে হয় না।

    আধুনিক computing-এর বিশাল complexity সামলানোর অন্যতম বড় কৌশল এটাই — প্রতিটা layer নিজের কাজটা করে, আর অন্য layer-এর সঙ্গে একটা defined interface দিয়ে কথা বলে।

    // এই আর্টিকেলে কী শিখলাম
    • Keyboard-এর ভেতরে নিজের একটা controller আছে — সে সারি-কলামের matrix scan করে, input report বানায়, USB HID দিয়ে পাঠায়।
    • Interrupt হলো CPU-কে hardware event জানানোর একটা mechanism — আর interrupt আসা মানেই context switch নয়।
    • OS-এর input machinery event তৈরি করে, focused application-এর জন্য deliver করে; দরকার হলে scheduler তাকে CPU-তে চালায়।
    • Application event handle করে নিজের state বদলায়; font system অক্ষরের shape-কে rasterize করে pixel information বানায়।
    • Compositor → final frame → display buffer → cable → monitor-এর pixel আলো ছাড়ে। ঘুরে সেই electrical signal-এই ফেরত।
    • প্রতিটা layer নিজের কাজ করে আর defined interface দিয়ে পরেরজনের সঙ্গে কথা বলে — এটাই abstraction।
    08

    সিরিজের শেষে

    আটটা আর্টিকেল আগে শুরু করেছিলাম একটা সহজ প্রশ্ন দিয়ে — x = 5 লিখলে সেই ৫ সংখ্যাটা কম্পিউটারের কোথায় যায়?

    উত্তরটা খুঁজতে গিয়ে আমাদের অনেক দূর যেতে হয়েছে। Transistor থেকে শুরু করে logic gate, gate থেকে latch, latch থেকে register। তারপর binary representation, CPU-র ভেতরের ALU আর datapath, fetch-decode-execute-এর অবিরাম চক্র। এরপর memory hierarchy, cache-এর চতুরতা, locality-র সৌন্দর্য। তারপর operating system — process, scheduling, virtual memory, system call। আর শেষে compiler, interpreter, bytecode, VM আর JIT — source code কীভাবে execution-এর দিকে এগোয়।

    সবশেষে keyboard-এর অক্ষর থেকে screen-এর অক্ষর পর্যন্ত পুরো journey-টা একসাথে দেখলাম।

    এই সিরিজ পড়ে আপনি নতুন CPU design করতে পারবেন না। সেটা উদ্দেশ্যও ছিল না। উদ্দেশ্য ছিল একটা mental map তৈরি করা।

    আমরা প্রতিদিন এমন সব tool ব্যবহার করি যাদের ভেতরের অনেক layer নিয়ে ভাবি না। React লিখি, browser-এর rendering system নিয়ে না ভেবেও। Docker চালাই, container-এর নিচে কী হচ্ছে না জেনেও। এটা খারাপ কিছু নয় — abstraction-এর উদ্দেশ্যই তো আপনাকে সব layer একসাথে মাথায় রাখতে না দেওয়া।

    কিন্তু কিছু ভেঙে গেলে সেই abstraction-এর নিচে একটু তাকাতে পারা কাজে দেয়। App slow হলে এখন অন্তত ভাবতে পারবেন — computation, memory, I/O, scheduling, rendering, নাকি অন্য কোনো layer? Memory নিয়ে সমস্যা হলে heap আর virtual memory-র কথা মনে পড়বে। Input বা display নিয়ে গোলমাল হলে keyboard থেকে screen পর্যন্ত এই পুরো chain-টা মাথায় আসতে পারে।

    সবচেয়ে বড় কথা, machine আর আগের মতো রহস্যময় থাকবে না। ঢাকনা খুলে ইঞ্জিনটা একবার দেখা হয়ে গেছে। ভেতরে কোনো জাদু নেই — আছে electrical signal, logic, software, interface, আর মানুষের তৈরি অনেকগুলো চতুর abstraction।

    সেটুকু জানাই যথেষ্ট।

    পড়ার জন্য ধন্যবাদ। ভালো থাকবেন।

    09

    আরও গভীরে যেতে চাইলে

    এই সিরিজ ছিল একটা পাখির চোখে দেখা। প্রতিটা topic-ই নিজে একটা পূর্ণ জগত। কোনো একটা layer যদি আপনার ভালো লেগে থাকে, নিচের resource-গুলো থেকে শুরু করতে পারেন। বেশিরভাগই বিনামূল্যে পাওয়া যায়।

    একদম শুরু থেকে বুঝতে চাইলে
    Crash Course Computer Science — YouTube-এ ৪০ পর্বের একটা সিরিজ, প্রতিটা ১০-১৫ মিনিট। Transistor থেকে AI পর্যন্ত computing-এর অনেকগুলো গুরুত্বপূর্ণ idea সহজভাবে পরিচয় করিয়ে দেয়। ভাষা সহজ, উপস্থাপনা চমৎকার। শুরু করার জন্য একটা ভালো overview।
    Ben Eater — YouTube channel। এই ভদ্রলোক breadboard-এ তার দিয়ে একটা সম্পূর্ণ 8-bit computer বানিয়েছেন, আর প্রতিটা ধাপ ক্যামেরার সামনে ব্যাখ্যা করেছেন। Article 1 আর 3-এ যা পড়েছেন, সেটা চোখের সামনে তৈরি হতে দেখতে পারবেন। ধৈর্য ধরে দেখার মতো জিনিস।
    Nand2Tetris (nand2tetris.org) — শুধু একটা NAND gate থেকে শুরু করে ধাপে ধাপে একটা পুরো computer system আর তার software hierarchy বানানোর কোর্স। CPU, assembler, VM, compiler, OS — সব নিজে হাতে project আকারে। Official website-এ lecture, project material আর tool বিনামূল্যে পাওয়া যায়; Coursera version-টা paid course। এই সিরিজের প্রায় সবকিছু এখানে হাতে-কলমে করে দেখা যাবে।
    Hardware আর CPU নিয়ে
    Computer Systems: A Programmer's Perspective — Bryant ও O'Hallaron-এর লেখা। Carnegie Mellon-এর বিখ্যাত বই। Programmer-এর দৃষ্টিকোণ থেকে লেখা, তাই আপনার কোডের সাথে hardware-এর সম্পর্ক কোথায় সেটা স্পষ্ট হয়। Article 3, 4, 5-এর গভীর version।
    Computer Organization and Design — Patterson ও Hennessy-র লেখা। Computer architecture-এর classic textbook। একটু ভারী, কিন্তু reference হিসেবে দাঁড়িয়ে থাকার মতো।
    Inside the Machine — Jon Stokes। আধুনিক processor-এর ভেতরটা ছবির সাহায্যে ব্যাখ্যা করা। Textbook-এর চেয়ে সহজ পাঠ।
    Memory আর Performance নিয়ে
    What Every Programmer Should Know About Memory — Ulrich Drepper-এর লেখা একটা দীর্ঘ প্রবন্ধ, বিনামূল্যে পাওয়া যায়। Article 5-এ যা ছুঁয়ে গেছি, তার সম্পূর্ণ রূপ। Cache, DRAM, NUMA — সব এখানে। খুঁজলেই PDF পাবেন।
    Latency Numbers Every Programmer Should Know — Jeff Dean-এর তৈরি একটা ছোট তালিকা, ইন্টারনেটে সহজেই পাওয়া যায়। বিভিন্ন operation-এ কত সময় লাগে তার একটা mental model তৈরি করে দেয়।
    Operating System নিয়ে
    Operating Systems: Three Easy Pieces (ostep.org) — Arpaci-Dusseau দম্পতির লেখা। সম্পূর্ণ বিনামূল্যে, PDF আকারে ওয়েবসাইটেই আছে। OS শেখার জন্য চমৎকার একটা বই — লেখার ধরন সহজ, উদাহরণ প্রচুর। Article 6-এর প্রতিটা বিষয় এখানে বিস্তারিত।
    Linux Kernel Development — Robert Love। Linux kernel-এর ভেতরটা কীভাবে কাজ করে জানতে চাইলে।
    Compiler আর Language নিয়ে
    Crafting Interpreters (craftinginterpreters.com) — Robert Nystrom-এর লেখা, ওয়েবসাইটে সম্পূর্ণ বিনামূল্যে পড়া যায়। নিজে হাতে দুইটা interpreter বানানোর মধ্য দিয়ে পুরো বিষয়টা শেখানো হয়। লেখার মান অসাধারণ — technical বই এত সুন্দরভাবে কম লেখা হয়।
    V8 blog (v8.dev/blog) — JavaScript engine-এর ভেতরে কী ঘটে, engineer-রা নিজেরাই লেখেন। JIT, garbage collection, optimization নিয়ে গভীর লেখা।
    হাতে-কলমে শিখতে চাইলে
    nandgame.com — ব্রাউজারেই NAND gate থেকে শুরু করে ধাপে ধাপে কম্পিউটার বানানোর একটা খেলা। বিনামূল্যে, মজার, আর শেখার জন্য চমৎকার।
    CS50 (Harvard) — YouTube আর edX-এ পাওয়া যায়; বর্তমান CS50x material free OpenCourseWare হিসেবেও available। C থেকে শুরু করে computer science-এর ভিত্তি, তারপর Python, SQL, web development। শিক্ষকতার মান অসাধারণ।

    আমি নিজেও আসলে এখানে দেওয়া প্রত্যেকটা রিসোর্স নিজে ঘেঁটে দেখার সুযোগ পাইনি। তবুও আপনাদের আর আমার নিজের সুবিধার্তে ইন্টারনেট ঘাঁটাঘাঁটি করে রিলেটেড সব রিসোর্স এখানে দিয়ে রাখলাম, যাতে পরে আরও এক্সপ্লোর করা যায়, আরও ভালোভাবে জানা যায়, নিজের জ্ঞানের কমতিগুলো শুধরানো যায়।

    শেষ কথা — এই তালিকা দেখে অভিভূত হওয়ার কিছু নেই। সবগুলো পড়তে হবে না। যে একটা জিনিস আপনার কৌতূহল জাগিয়েছে, সেটা নিয়েই শুরু করুন। বাকিটা সময়মতো আসবে।

    এই পাতা খোলার পর থেকে আপনার device-এ আনুমানিক ২৮৪.১ কোটি বার transistor switch হয়েছে।
    cd ~  # back to terminal