Programlama

Kod nasıl çalışır

Yazdığınız kod yalnızca metindir ve işlemci metin okumaz; herhangi bir şey olmadan önce makinenin çalıştırabileceği bir biçime çevrilmesi gerekir. Diller, bu çevirinin ne zaman yapıldığı ve sonucunun nerede tutulduğu konusunda ayrışır ve kafa karıştıran hataların çoğu tam olarak bu farktan gelir.

  • Ders 2 / 14
  • Başlangıç
  • Ücretsiz, kayıt yok

Her kod satırının geçtiği zincir

  1. 1 Yazdığınız metin

    Sıradan bir metin dosyası; disk açısından bir nottan farksız.

  2. 2 Söz dizimi denetimi

    Dosyanın tamamı üzerinde, herhangi bir çalıştırmadan önce. Burada kırılırsa tek satır çalışmaz.

  3. 3 Çalıştırılabilir biçime çeviri

    Bayt kodu, opcode ya da makine kodu. Kimi zaman diskte, kimi zaman bellekte, kimi zaman hiçbir yerde tutulur.

  4. 4 İşlemcide çalışma

    İşin gerçekten yapıldığı ve çalışma zamanı hatasının ortaya çıktığı tek yer.

Bu zincir sadeleştirilmiştir. Pratikte son iki halka arasında başka katmanlar da oturur; işletim sisteminden dil motorunun çalışırken yaptığı iyileştirmelere kadar.

Son kontrol: Bu dersteki bilgiler ve araç adları bu tarihte kaynaklarıyla yeniden doğrulanır.

Bilgisayar kodunuzun metnini okumaz; peki ne çalıştırır?

Kaydettiğiniz dosya düz metindir; disk açısından bir not dosyasından farkı yoktur. İşlemci o metni okumaz. İşlemcinin çalıştırdığı şey çok basit sayısal komutlardan oluşur: bu sayıyı bellekten al, şununla topla, sonucu oraya koy ve sıfır çıktıysa şu noktaya atla. Buna makine dili denir ve bugün kimse doğrudan onunla çalışmaz.

Yani metniniz ile işlemci arasında her zaman bir çeviri aşaması vardır. Üç halkası vardır ve sırası hiç değişmez: yazdığınız metin, o metni okuyup denetleyen ve çeviren program, ve sonunda çalışan çevrilmiş biçim. Hiçbir dil bu zincirden kaçamaz. Diller yalnızca iki konuda ayrışır: çeviri ne zaman yapılıyor ve sonucu saklanıyor mu.

Çok çabuk işinize yarayacak bir nokta: çeviri aşaması her şeyden önce söz dizimini denetler, yani metniniz o dilin kurallarına uyuyor mu diye bakar. Uymuyorsa iş tam orada durur ve programınızdan tek satır çalışmaz; hatadan önce yazılmış sağlam bir satır bile. Bu sayfanın dördüncü bölümü bunu iki gerçek dosyayla gösteriyor.

Derlenen ve yorumlanan arasındaki fark nedir?

En sade hali şu: yorumlanan bir dilde metin, dil motoruna olduğu gibi verilir ve yukarıdan aşağı çalışır; derlenen bir dilde metin önce başka bir biçime dönüştürülür ve çalışan şey o biçimdir. Mozilla da tam bu terimlerle anlatır: yorumlanan dillerde kod metin biçiminde alınır ve doğrudan ondan işlenir, derlenen diller ise çalıştırılmadan önce başka bir biçime dönüştürülür.

Şimdi rahatsız edici kısım. Bu ayrım artık temiz bir çizgi değil. Mozilla aynı sayfada, modern JavaScript yorumlayıcılarının çoğunun tam zamanında derleme denen bir teknik kullandığını, betik çalışırken kaynağı daha hızlı bir ikili biçime çevirdiğini ekliyor; yine de JavaScript'i yorumlanan sayıyor, çünkü o derleme önceden değil, çalışma anında oluyor.

Bu yüzden derlenen mi yorumlanan mı sorusu yavaş yavaş faydasını yitiriyor. Daha iyi iki soru var: çeviri ne zaman yapılıyor ve sonucu saklanıyor mu, yoksa her seferinde sıfırdan mı kuruluyor? Bu iki yanıt, bir C programının çalışmadan önce neden ayrı bir derleme adımı olduğunu ve modül içe aktaran bir Python betiğinin ikinci seferde neden biraz daha hızlı açıldığını açıklar.

Aynı iş için iki zamanlama

İkisi de çevirir. Fark, çevirinin olup olmadığında değil, ne zaman olduğundadır.

Çalışmadan önce çevrilen

  • Kendinizin çalıştırdığı ayrı bir derleme adımı vardır
  • Çıktı, diskte kalan çalıştırılabilir bir dosyadır
  • Pek çok hata ilk çalıştırmadan önce bulunur
  • Dosyayı değiştirmek, yeniden derlemedikçe etki etmez

Çalışırken çevrilen

  • Ayrı adım yok; dosyayı verirsiniz ve çalışır
  • Çeviri sonucu bellekte ya da diskte tutulabilir
  • Pek çok hata o satıra ulaşılana kadar bulunmaz
  • Dosyayı değiştirirsiniz ve etkisini bir sonraki sefer görürsünüz

Bu iki sütun artık tam olarak ayrı değil: modern motorların çoğu ikisini birden yapar ve etiketi işe yaramaz kılan da budur.

Python, JavaScript ve PHP bu zincirin neresinde?

Aşağıdaki tablo, önceki bölümdeki iki soruyu dört dile uyguluyor. Üçüncü sütun önemli olan, çünkü diller etiketlerinde değil orada ayrışır.

DilOnu ne çevirirÇeviri ne üretirNerede çalışır
PythonPython yorumlayıcısıBayt kodu; modüller için diskte bir __pycache__ klasöründe tutulurAynı makine ya da sunucu
JavaScriptTarayıcı motoru ya da sunucuda NodeÇalışırken kurulan makine kodu, diskte hiçbir yerde tutulmazKullanıcının tarayıcısı ya da bir sunucu
PHPPHP motoruOpcode; opcache tarafından diskte değil sunucu belleğinde tutulurSunucu
CBir derleyici, çalıştırmadan önce ayrı bir adımdaDiskte çalıştırılabilir bir dosyaDoğrudan işletim sisteminde

İlk üç satırı yan yana koyun, bir örüntü çıkar: üçü de çalışma anında çevirir ve yalnızca sonucu nereye koyduklarında ayrışır. Python diske, PHP belleğe, JavaScript hiçbir yere. Dördüncü satır, gerçekten farklı olan durumu görün diye bilerek burada: C'de programı derlemezseniz çalıştırılacak hiçbir şey yoktur.

Hemen kullanabileceğiniz pratik bir sonuç: JavaScript, PHP ve Python'da dosyayı değiştirirsiniz ve etkisini bir sonraki sefer görürsünüz. C'de yeniden derlemeniz gerekir. Biri size dosyayı değiştirdiğini ama hiçbir şeyin değişmediğini söylerse, ilk soru dilinin bu tablonun hangi satırında olduğu, ikinci soru ise beşinci bölümün konusudur.

Neden bazen hiçbir satır çalışmaz, bazen programın yarısı çalışır?

İki küçük dosya oluşturun ve her birini ayrı çalıştırın. İlki bad.py, ikinci satırda kapatılmamış bir parantezle:

print("first line")
print("second line"

Gerçek çıktı şu:

  File "bad.py", line 2
    print("second line"
         ^
SyntaxError: '(' was never closed

İkincisi boom.py; söz dizimi doğru ama imkansız bir şey istiyor:

print("first line")
print(1/0)

Ve çıktısı:

first line
Traceback (most recent call last):
  File "boom.py", line 2, in <module>
    print(1/0)
          ~^~
ZeroDivisionError: division by zero

Farka bakın, çünkü bu tek şey hata ayıklamanızın yarısıdır. İlk dosyada first line sözleri hiç yazdırılmadı; oysa birinci satır tamamen doğruydu ve hatadan önce geliyordu. İkincisinde yazdırıldı ve program yolun ortasında düştü. Sebebi birinci bölümdeki zincir: söz dizimi denetimi, herhangi bir çalıştırmadan önce dosyanın tamamı üzerinde yapılır; bu yüzden ikinci satırdaki kapatılmamış bir parantez birinci satırı da beraberinde götürür. Sıfıra bölme ise ona gerçekten ulaşana kadar keşfedilmez, çünkü o ana kadar bölenin sıfır olduğunu kimse bilmez.

Bu iki durumun adı var: söz dizimi hatası ve çalışma zamanı hatası. Pratik değeri şu: dili bilmeseniz bile ikisini yalnızca çıktıya bakarak ayırt edebilirsiniz. Hata mesajından önce bir şey yazdırıldıysa program çalışmaya başlamıştı ve karşınızda bir çalışma zamanı hatası var; hiçbir şey yazdırılmadıysa büyük ihtimalle hiç çalışmamıştır.

Hatanın türünü belirleyen tek soru

Hata mesajından önce program bir şey yazdırmış mıydı?

Hayır, hiçbir şey

Söz dizimi hatası

  • Program hiç başlamadı; söz dizimi denetimi çalıştırmadan önce kırıldı
  • Mesajdaki satır numarası genelde doğrudur ya da bir iki satır aşağıdadır
  • Eksik bir parantez, tırnak ya da iki nokta arayın
Evet, bir şey yazdırıldı

Çalışma zamanı hatası

  • Program çalıştı ve yolun ortasında mümkün olmayan bir şeye çarptı
  • Mesajın son satırı hata türünü söyler ve en önemlisidir
  • Değerleri tam orada yazdırın ve hangisinin sandığınız gibi olmadığını görün

Bu soru hatanın türünü söyler, sebebini değil. Hiç hata vermeden yanlış yanıt veren bir program iki dala da girmez.

Kaydettiğiniz dosya, çalışan şey değildir

Şimdi zincirin ilginç kısmı. Çevirinin sonucu yalnızca bellekte yaşamaz; çoğu zaman bir dahaki sefere yeniden kurulması gerekmesin diye saklanır. Python bunu gözünüzün önünde yapar. İki dosya oluşturun, tools.py ve onu içe aktaran bir main.py, sonra:

python3 main.py
ls __pycache__/

__pycache__ adlı bir klasör belirir ve içinde tam olarak bir dosya vardır: tools.cpython-312.pyc. main.py için hiçbir şey yazılmamıştır. Python'ın kendi belgeleri her iki yarıyı da açıklar: Python her modülün derlenmiş sürümünü __pycache__ dizininde önbelleğe alır ve doğrudan komut satırından yüklenen modülü her zaman yeniden derler, sonucu saklamaz.

PHP aynı işi tek farkla yapar: sonucu diske koymaz, sunucu belleğinde tutar. Bu katmanın adı opcache ve davranışının, yeni başlayanları çıldırtan tek bir ayarı var: diskteki dosyanın değişip değişmediğini ne sıklıkla denetleyeceği. PHP'nin kendi el kitabı ayarı tam bu sözlerle tarif ediyor: betik zaman damgalarının güncellenme denetimi ne sıklıkla yapılsın, saniye cinsinden. Yani dosyayı kaydetmekle kaydın etki etmesi arasında bir boşluk vardır ve bu boşluk bilinçlidir.

Dolayısıyla o bildik cümlenin, dosyayı değiştirdim ama hiçbir şey olmadı, üç yaygın yanıtı vardır ve üçü de bu zincirin içindedir: ya değiştirdiğiniz dosya çalışan dosya değildir, ya eski bir çevrilmiş kopya hala bellektedir, ya da çıktı daha ileride bir önbellek katmanından gelmektedir ve programınıza hiç ulaşmamıştır. Bu sayfanın altındaki kendi işimizden bölümü, o ayarın kendi sunucumuzdaki değerini veriyor.

Metniniz ile metal arasında duran katmanlar

  1. 1

    İşlemci

    Gerçekten çalıştıran tek şey ve yalnızca basit sayısal komutları anlar.

  2. 2

    İşletim sistemi

    Belleği, dosyaları ve işlemci zamanını programlar arasında paylaştırır.

  3. 3

    Dil motoru

    Python yorumlayıcısı, tarayıcının JavaScript motoru ya da sunucudaki PHP motoru.

  4. 4

    Çevrilmiş biçim

    Bayt kodu, opcode ya da makine kodu; gerçekten okunup çalıştırılan şey.

  5. 5

    Sizin metin dosyanız

    En dıştaki katman ve doğrudan değiştirdiğiniz tek katman.

Numaralar önem sırası değil, uzaklık sırasıdır. Günlük programlama bu katmanların hiçbirini öğrenmenizi gerektirmez; yalnızca var olduklarını bilmenizi ister.

Program çalışmadığında önce nereye bakarsınız?

Hata mesajını yukarıdan değil aşağıdan okuyun. Son satır hatanın türünü söyler ve ekrandaki en önemli kelime odur; üstündeki satır ise genelde nerede olduğunu söyler. Dördüncü bölümdeki örnekte son satır ZeroDivisionError: division by zero idi ve üstündeki satır patlayan ifadeyi tam olarak gösteriyordu. Yeni başlayanlar genelde yalnızca dosya yollarının yazdığı en üstten başlar, sonra da hatanın anlaşılmaz olduğunu söyler.

Okuduktan sonra katmanı adlandırın. Yalnızca dört tane var. Söz dizimi: hiçbir şey çalışmadı, mesaj herhangi bir çıktıdan önce geldi. Çalışma zamanı: bir şey yazdırıldı, sonra düştü. Ortam: program sağlam ama ihtiyaç duyduğu bir şey kurulu değil, sürümü farklı ya da bulunamıyor. Mantık: hiç hata yok, program sonuna kadar çalışıyor ve yanlış yanıt veriyor.

Tutumumuz şu ve basit: tek bir karakteri değiştirmeden önce katmanın adını yüksek sesle söyleyin. Yeni başlayanların kaybettiği saatlerin çoğu, sorunun bulunmadığı bir katmanda kodu değiştirmekle geçer; kütüphane hiç kurulmamışken gayet sağlam bir fonksiyonu yeniden yazmak gibi. Dördüncü katman hepsinin en kötüsüdür, çünkü hiç hata vermez; onu yakalamanın tek yolu, çalıştırmadan önce çıktının ne olması gerektiğini tahmin edip sonra çıkanla karşılaştırmaktır.

Yapay zekayla hızlı yol

Bir dil modelinin yeni başlayan biri için gerçekten hızlandırdığı şey hata mesajı okumaktır, ama yalnızca sırayı korursanız. Yaygın hata, sorunun nerede olduğunu tahmin edip o tahmini sormaktır; geri gelen şey hatayla değil, tahmininizle ilgili bir yanıt olur. Aşağıdaki reçete sırayı tersine çevirir: önce katman, sonra açıklama, en son değişiklik. Bu iş teşhis olduğu için üst sınıf bir model daha uygundur; güncel tercihimiz bu sitenin yapay zeka bölümünde.

  1. Hatanın tam metnini ilk satırdan sonuncuya kadar kopyalayın. Ekran görüntüsü değil, özet değil, yalnızca son satır da değil; üstteki satırlar olayın yerini taşır.
  2. Herhangi bir açıklamadan önce yalnızca katmanın adlandırılmasını isteyin: söz dizimi, çalışma zamanı, ortam ya da mantık. Tek kelime yeter ve sonrasını o tek kelime belirler.
  3. Hatanın işaret ettiği kod satırınızı birebir alıntılamasını isteyin. Yapamıyorsa kodunuza henüz sahip değildir ve söylediği her şey tahmindir.
  4. Şimdi açıklamayı ve mümkün olan en küçük değişikliği isteyin, dosyanın yeniden yazılmasını değil. Tam bir yeniden yazım hatayı gizler ve ne olduğunu hiç öğrenemezsiniz.
  5. Değişikliği kendiniz uygulayıp çalıştırın; yine hata verirse birinci adımdan başlayın. Katman ortamsa, bir sonraki mesajda dil sürümünüzü ve işletim sisteminizi de yazın.

Kopyalamaya hazır şablon

Bu hatayı aldım. Herhangi bir açıklamadan önce yalnızca aşağıdaki üç soruyu, bu sırayla yanıtla.

1. Bu hata hangi katmanda? Tam olarak birini seç: söz dizimi, çalışma zamanı, ortam, mantık.
2. Kodumun hangi satırı buna yol açtı? O satırı birebir alıntıla. Kod elinde yoksa neye ihtiyacın olduğunu söyle.
3. Bunu düzelten en küçük değişiklik nedir? Yalnızca o değişiklik, dosyanın geri kalanını yeniden yazmadan.

Hatanın tam metni:
{buraya yapıştırın, ilk satırdan sonuncuya}

Çalıştırdığım kod:
{buraya yapıştırın}

Ortam: {işletim sistemi} üzerinde {dil sürümü}

Çıktıya güvenmeden önce: Modelin en kötü tahmin ettiği katman ortamdır, çünkü bilgisayarınızı göremez: dil sürümünüzü, işletim sisteminizi ve neler kurduğunuzu bilmez; bunları vermezseniz boşluğu bir tahminle doldurur. Bu yüzden önerdiği her dosya yolunu ya da komut adını çalıştırmadan önce basit bir denetimle doğrulayın. Birinci adımın yanıtı, çıktıda kendi gördüğünüzle çelişiyorsa yanıta değil çıktıya güvenin.

Bu işte yapay zeka

Bir alışkanlık, yeni başlayan birinin hızını her şeyden çok artırır: hata metnini forumlarda aramak yerine tam metni bir modele verip açıklamasını istemek. Eskiden bir saatlik arama gerektiren şey artık tek bir mesaj. Tutumumuz şu: bunun da bir sırası var; önce katman, sonra açıklama. Tersi, üretkenlik kostümü giymiş bir vakit kaybıdır.

Gerçekten işe yarayan araçlar

  • Claude Uzun bir hata mesajını okumakta ve hangi satırının önemli olduğunu söylemekte iyi; özellikle tam metni özetlemeden verdiğinizde. İran, Anthropic'in iki desteklenen ülke listesinin hiçbirinde yok; bunu ağ testiyle değil, Anthropic'in kendi sayfasında okuduk.
  • Gemini Farsçayı iyi anlar ve bayt kodu, opcode ve tam zamanında derleme gibi terimlerin anlamını sormak için yeterlidir. Google'ın kendi sayfası Gemini web uygulamasının 230'dan fazla ülke ve bölgede çalıştığını söylüyor ve İran o listede yok.
  • ChatGPT En yaygın seçim ve hata okumak için kabul edilebilir. Yapay zeka bölümümüzde henüz ona ait bir kayıt yok, bu yüzden erişimi ya da fiyatı hakkında burada bir iddiada bulunmuyoruz.

Nerede geri teper

Buradaki risk özellikle bu derse ait: model, sorunuzun işaret ettiği katmanda yanıt verir ve yeni başlayan birinin sorusu genelde yanlış katmanı adlandırır. Asıl sorun kurulmamış bir kütüphaneyken döngünüzün neden çalışmadığını sorun; döngülerle ilgili, sebeple hiç ilgisi olmayan ve size bir saate mal olabilecek ayrıntılı bir yanıt alırsınız. Çaresi bu sayfadaki hızlı yol: önce tam hata metni, sonra katman, sonra açıklama. Ortam katmanı hepsinin en tehlikelisidir, çünkü model bilgisayarınızı göremez ve sürümleri vermezseniz boşluğu tahminle doldurur; Anthropic bunu kendi belgelerinde halüsinasyon diye adlandırıp azaltma yollarını anlatıyor, yani üretici de bunu gerçek bir zayıflık sayıyor. Kural basit: modelin sisteminiz hakkında söylediği her şey, tonunun kendinden eminliğiyle değil, gerçek bir çalıştırmayla ölçülmelidir. Bu araçların İran'dan nasıl ödenebileceği için satın alma rehberine bakın.

Kaynaklar: Anthropic: reduce hallucinations Anthropic: supported countries Google: where the Gemini web app is available

Bu tavsiyenin sınırı

Bu zinciri anlamak hiçbir şeyi onarmaz; yalnızca bir şeyi onarırken doğru yere bakmanızı sağlar. Bu sayfadaki model de bilerek sadeleştirilmiştir: tam zamanında derleme, çöp toplama, dil motorunun çalışırken yaptığı iyileştirmeler ve işletim sisteminin zamanlaması, her biri kendi başına bir alandır ve burada yalnızca adları geçti. Dört katmanlı ayrım da resmi bir sınıflandırma değil, çalışan bir araçtır; pratikte tek bir hatanın kökleri aynı anda iki katmanda olabilir. Bir sonraki bölümdeki opcache değeri de bize aittir: sizin barındırmanızda sıfır olabilir, yani her istekte denetlenir, ya da tamamen kapalı olabilir.

Kendi işimizden

Bu dersin denetlendiği gün, beşinci bölümün iki yarısını da tam olarak bu sunucuda ölçtük. Önce Python: bir tools.py içe aktaran bir main.py çalıştırıldı ve ardından __pycache__ klasöründe tam olarak bir dosya vardı, tools.cpython-312.pyc; main.py için hiçbir şey yazılmamıştı. Sonra PHP: bu sunucuda opcache.revalidate_freq ayarı 60. Bu öğrenme bölümünün bir veri dosyasını bir istekten bir saniye sonra değiştirdik ve sayfayı beş saniyede bir çektik; 43 saniye boyunca eski değer gelmeye devam etti, 48. saniyede yenisi belirdi. Yani bir dakikaya yakın süre boyunca her ziyaretçiye PHP'nin daha önce derlediği bir kopya sunuldu; oysa diskteki dosya ilk saniyeden beri değişmişti. Kendi sunucunuza erişiminiz varsa aynısını php -i | grep opcache.revalidate_freq ile görün.

Gerçek devam soruları

Bayt kodu ne demek?

Ara bir biçimdir: ne insanın okuyabileceği metin ne de doğrudan bir işlemci komutu. Dil yorumlayıcısı kodunuzu bayt koduna çevirir ve sonra onu kendisi çalıştırır; dönüşüm bir kez olduğu için saklanması bir sonraki çalıştırmayı hızlandırır. Bir __pycache__ klasöründeki dosyalar tam olarak budur.

Bazı diller neden daha hızlı?

Çünkü çalışma anına daha az iş bırakırlar. Çalışmadan önce derlenen bir dil kararların çoğunu önceden vermiştir; çalışırken çeviren ve veri türlerini o anda çözen bir dil ise aynı işi çalışmanın ortasında yapmak zorundadır. Ama çoğu web sitesi için dil hiç darboğaz değildir; veritabanı, ağ ve ağır görseller çok daha önce kendini gösterir.

Dosyayı değiştirdim ama site değişmedi; sorun nerede?

Üç yaygın yanıtı var ve üçü de bu zincirin içinde. Ya değiştirdiğiniz dosya çalışan dosya değildir; örneğin başka bir klasörden başka bir kopya yüklenir. Ya eski bir çevrilmiş kopya hala sunucu belleğindedir ve denetim aralığı geçene kadar değişmez. Ya da çıktı daha ileride bir önbellek katmanından gelmektedir ve programınıza hiç ulaşmamıştır.