← All blogs

01010110 → 🚀

Viktor Ahmeti.4 months ago

Programimi si fushë ka avancuar shumë prej shekullit të kaluar. Si është e mundur që sot me dy-tri fjalë anglisht të krijohet një uebfaqe funksionale, kur para 50 vitesh kjo gjë do të kërkonte disa javë apo muaj punë nga ekspertë të kompjuterit? Në këtë artikull do të eksplorojmë se çka ndodh në prapaskenë kur ne shkruajmë kod në një gjuhë si C++, Python, apo JavaScript.

Kujdes: Gjithçka që diskutohet në këtë artikull në një nivel të lartë dhe tejkalohen shumë teknikalitete të cilat nuk kanë shumë rëndësi për temën në diskutim

Kodi i Makinës

Kompjuteri, ose më mirë të themi Procesori, nuk kupton as Java as Python. Si qendra procesuese e kompjuterit, procesori funksionon me rrymë dhe e vetmja gjuhë që kupton është rryma. Për ti dhënë kuptim rrymës, vendoset një kufi midis “tensionit të lartë” dhe “tensionit të ulët”. Çdo puls i rrymës me tension nën atë kufi interpretohet si 0 kurse pulset atë mbi kufi interpretohen si 1. Dhe gjithçka mund të arrihet vetëm me këta dy numra.

Shkronja “V” sipas standardit ASCII

Në foton më lart shohim se në çdo puls të rrymës tensionet interpretohen sikur 0 ose 1. Ky sistem quhet sistemi binar dhe është mënyra se si çdo kompjuter sot funksionon. Mund të ju shkojë mendja se a mund të ekzistojë një kompjuter ternar apo edhe me sistem decimal, e përgjigja është po, mirëpo janë shumë më të ndjeshëm ndaj lëvizjeve në tension.

Logjikisht rrjedh pyetja “Si mundet procesori ti interpretojë njëshat dhe zerot”? Procesori përbëhet nga miliarda tranzistorë që krijojnë porta logjike që krijojnë konstrukte edhe më komplekse e abstrakte. Prodhuesit e ndërtojnë procesorin me një arktitekturë specifike ku i definojnë saktë se çka bëjnë pulset elektrike. Kombinimet binare që i kupton procesori quhen Bashkësi të Udhëzimeve (Instruction Sets). Nëse doni ti shikoni, këto janë udhëzimet për arkitekturën X86 kurse këto për arkitekturën ARM.

Këto udhëzime mund ta bëjnë procesorin të ruajë një vlerë në RAM, të mbledhë dy numra, apo diçka tjetër të thjeshtë. Për shkak se bashkësitë e udhëzimeve i kanë të ndryshme, qartazi programi i njejtë nuk mund të kuptohet nga të dy arkitekturat – arsyeja e parë pse programet e laptopëve (shumica me procesor në familjen X86) nuk funskionojnë në telefona (të gjithë me procesor në familjen ARM).

Telefonët dhe kompjuterët me procesorë me arkitektura të ndryshme

Me Program nënkuptojmë listën e udhëzimeve të ruajtura në RAM të cilat procesori i ekzekuton në mënyrë të njëpasnjëshme. Pra, një program është thjeshtë një varg i gjatë i njëshave dhe zerove. Dhe vërtetë kështu ishte: Ekspertët shkruanin kod direkt me zero dhe njësha, gjë që ishte shumë e vështirë dhe e mundimshme.

Assembly

Si të shkruajmë programet më lehtë? Gjuha e parë programuese ishte Assembly. Në këtë gjuhë në vend të zerove dhe njëshave shkruajmë fjalë dhe numra. Për shembull, ja një program për X86 i cili e merr numrin 7 dhe e vendos në regjistrin AL:

BinaryAssembly
10110000 00000001MOV AL, 0x7

Kjo lejon që programet të shkruhen me fjalë si MOV, ADD, JMP, PUSH, etj, të cilat mbahen mend dhe lexohen shumë më lehtë. Si koncept duket perfekt por, siç e pamë më herët, kompjuteri kupton vetëm binar kështu që programi ynë Assembly duhet të konvertohet në Binar.

Programi i cili e kthen kodin Assembly në Binar quhet Përpilues (Compiler). Vetë programi i përpiluesit mund të shkruhet në Binar ose edhe në Assembly përmes një metode që quhet Bootstrapping. Prapseprapë, nuk ndaloi hovi për të krijuar gjuhë programuese sa më të thjeshta, abstrakte, dhe të lexueshme.

C

Prej gjuhëve më të thjeshta programuese e cila përdoret shumë edhe sot është gjuha C. Kjo gjuhë ishte kulminacioni i tentimeve të shumë gjuhëve të tjera të bëjnë programimin më abstrakt. Gjuha C nuk përkthehet 1 me 1 në gjuhë të makinës. Ajo përmban abstraksione si variablat, operatorët, procedurat, funksionet, dhe tipet, që ne sot i përdorim dhe i njohim shumë mirë. Shikoni sa i lexueshëm është programi i cili i mbledh dy numra:

#include <stdio.h>
//një funksion
int main() {  
    //deklarim i variablave
    int number1, number2, sum;
    
    printf("Shkruaj dy numra: ");
    scanf("%d %d", &number1, &number2);
    
    //mbledhja e numrave
    sum = number1 + number2;      
    
    printf("%d + %d = %d", number1, number2, sum);
    
    return 0;
}

Gjuha C e bëri më të lehtë kyçjen e njerëzve në zhvillim të softuerit sepse ishte e lehtë për të marrë hapat e parë. Prapseprapë ne sot nuk mund ta imagjinojmë një botë ku duhet të shkruajmë kod për një procesor të zhveshur: nuk ka librari për sysout, për punë me files, për të shfaqur diçka në ekran, etj – gjithçka duhet të shkruhej nga fillimi.

Sistemet Operative

Shumë shpesh e harrojmë rëndësinë e Sistemeve Operative në jetën tonë. Ato janë pika kyçe e zhvillimit kaq të hovshëm të teknologjisë në të gjithë botën. Ne njohim Sisteme Operative si Windows, Linux, MacOS, dhe Android por le të kuptojmë më saktë çka nënkuptojmë me fjalën OS dhe ku është benefiti i tyre.

Disa sisteme të njohura operative

Si të gjithë programet tjera, edhe Sistemi Operativ është program që ekzekutohet në procesor. Prej qëllimeve kryesore të tij janë:

Kur Sistemi Operativ është duke u ekzekutuar në kompjuter, të gjitha programet tjera ekzekutohen nën mbikqyrjen e tij. Përmes system calls programet e tjera mund të ndërveprojnë me sistemin e fajllave, të dërgojnë kërkesa në internet, apo të shfaqin dritare në ekran duke i përdorur këto mundësi të gatshme nga Sistemi Operativ.

Pra, tani e tutje duhet ta keni parasysh se libraritë e ofruara nga të gjitha gjuhët programuese janë të mundësuara direkt nga Sistemi Operativ i cili i bën të gjitha punët e vështira.

Java dhe C#

Programet e shkruara me C dhe C++ përpilohen direkt në kod të makinës. Kjo do të thotë se duhet të bëhet një përpilim unik për të gjitha kombinimet e arkitekturave të CPU dhe sistemeve operative.

Gjuhët moderne jo vetëm që kanë shtuar abstraksione të reja si Object-Oriented-Programming por kanë ndryshuar edhe mënyrën e përpilimit të programeve. Një Runtime Environment është një program i cili (nën mbikqyrjen e Sistemit Operativ) ka për detyrë të ekzekutojë një program të shkruar të një gjuhë të lartë programuese.

Të flasim më konkretisht. Runtime Environment i cili e ekzukuton Java quhet JVM. Nga shumë implementime të tij, ai mund të instalohet në çfarëdo CPU dhe OS. Një program Java së pari përpilohet në një gjuhë universale të quajtur bytecode. Ky bytecode pastaj mund të ekzekutohet nga JVM në çfarëdo platforme!

Si funksionon Java

Përsëri na u shfaq e njëjta gjë: OS e bën punën e vështirë për JVM kurse JVM bën punën e vështirë për Java. Kjo metodologji nuk është unike për Java. Gjuha C# ekzekutohet nga .NET, gjuha Python ekzekutohet nga CPython, etj. Ekosistemi gjithashtu është shumë i gjerë sepse ka shumë implementime të Runitimes po ka edhe shumë gjuhë që ekzekutohen nga to, si Scala dhe Kotlin në JVM apo F# dhe VB në .NET.

JavaScript dhe TypeScript

Shumë programerë e përdorin JavaScript por ndoshta nuk ja kanë idenë se si ekzekutohet. JavaScript ekzekutohet nga një Runtime (apo engine) sikur gjuhët që i përmendëm më lart. Në çdo Shfletues gjendet një program që i ekzekuton programet JavaScript: Chrome e ka V8, Mozilla e ka SpiderMonkey, Edge e ka Chakra. Çka është interesante është se ndërveprimi i JavaScript me Shfletuesin mundësohet nga librari të ofruara nga shfletuesi, si për shembull manipulimi me DOM.

Në ditët e sotme JavaScript ekzekutohet edhe pa Shfletues. Runtime V8 është shkoqur nga Chrome për të ekzekutuar JavaScript direkt në kompjuter, normalisht pa ato libraritë për DOM të cilat nuk kanë kuptim këtu. Edhe këtu ka implementues të ndryshëm si NodeJs, Deno, dhe Bun. Le të shkojmë edhe një nivel më tutje…

TypeScript është një gjuhë (superset i JavaScript) e cila i shton tipet dhe shumë komoditete tjera JS. Çka e bën atë interesante është se nuk ka një Runtime të saj por vetëm përpilohet (transpilohet) në JavaScript të pastër, me ndonjë vegël si Babel, i cili pastaj ekzekutohet nga V8.

Transpilimi i TypeScript

Edhe më abstrakte

Sot ekosistemi i zhvillimit të softuerit është aq i mbushur me vegla sa që është shumë vështirë të kuptohet se çka janë, a duhen, dhe pse ekzistojnë fillimisht.

Libraritë janë programe të gatshme të cilat mund ti inkuadrosh në programin tënd nëse të duhen. Ato mund të jenë të thjeshta si shfaqja e grafeve apo konvertimi i orës, apo edhe më komplekse si React që ofron një mini-metodologji pune për ueb.

Frameworks janë programe që të përcaktojnë një metodologji pune për të arritur një qëllim të caktuar. Për shembull NextJs është framework që sistemon zhvillimin e frontendit me React, apo NestJs që sistemon zhvillimin e APIs me JavaScript duke përdorur ndonjë nën-librari si Express. Mos të shkojmë më tutje me Spring apo .NET Core që janë frameworks me dhjetra librari të ndryshme që mundësojnë komunikim përmes HTTP, ndërveprim me baza të dhënash, autorizim të klientëve, (de)serializimin e JSON, ndryshimin e HTML, e mijëra gjëra tjera.

Disa prej temave që prekëm sot, secila me nga njëmijë nën-tema të fshehura për ti eksploruar

Konkluzion

Ekosistemi është i gjerë – aq i gjerë sa që është i pamundur të përmendet e lëre më të mësohet. Po e mbyll këtë artikull njejtë siç e hapa. Si është e mundur që sot me dy-tri fjalë anglisht të krijohet një uebfaqe funksionale, kur para 50 vitesh kjo gjë do të kërkonte disa javë apo muaj punë nga ekspertë të kompjuterit?

← All blogs